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