v / examples / veb_orm_jwt / auth_services.v
91 lines · 71 sloc · 2.14 KB · b474aa0faf8d055aaced80ed0687ac354d0864a0
Raw
1module main
2
3import crypto.hmac
4import crypto.sha256
5import crypto.bcrypt
6import encoding.base64
7import json
8import databases
9import time
10import os
11
12struct JwtHeader {
13 alg string
14 typ string
15}
16
17struct JwtPayload {
18 sub string // (subject) = Entity to whom the token belongs, usually the user ID;
19 iss string // (issuer) = Token issuer;
20 exp string // (expiration) = Timestamp of when the token will expire;
21 iat time.Time // (issued at) = Timestamp of when the token was created;
22 aud string // (audience) = Token recipient, represents the application that will use it.
23 name string
24 roles string
25 permissions string
26}
27
28fn (mut app App) service_auth(username string, password string) !string {
29 mut db := databases.create_db_connection() or {
30 eprintln(err)
31 panic(err)
32 }
33
34 users := sql db {
35 select from User where username == username
36 }!
37
38 if users.len == 0 {
39 return error('user not found')
40 }
41
42 user := users.first()
43 if !user.active {
44 return error('user is not active')
45 }
46
47 db.close()!
48
49 bcrypt.compare_hash_and_password(password.bytes(), user.password.bytes()) or {
50 return error('Failed to auth user, ${err}')
51 }
52
53 token := make_token(user)
54
55 return token
56}
57
58fn make_token(user User) string {
59 secret := os.getenv('SECRET_KEY')
60
61 jwt_header := JwtHeader{'HS256', 'JWT'}
62 jwt_payload := JwtPayload{
63 sub: '${user.id}'
64 name: '${user.username}'
65 iat: time.now()
66 }
67
68 header := base64.url_encode(json.encode(jwt_header).bytes())
69 payload := base64.url_encode(json.encode(jwt_payload).bytes())
70 signature := base64.url_encode(hmac.new(secret.bytes(), '${header}.${payload}'.bytes(),
71 sha256.sum, sha256.block_size).bytestr().bytes())
72
73 jwt := '${header}.${payload}.${signature}'
74
75 return jwt
76}
77
78fn auth_verify(token string) bool {
79 if token == '' {
80 return false
81 }
82 secret := os.getenv('SECRET_KEY')
83 token_split := token.split('.')
84
85 signature_mirror := hmac.new(secret.bytes(), '${token_split[0]}.${token_split[1]}'.bytes(),
86 sha256.sum, sha256.block_size).bytestr().bytes()
87
88 signature_from_token := base64.url_decode(token_split[2])
89
90 return hmac.equal(signature_from_token, signature_mirror)
91}
92