Xác thực user trong Rails app của bạn với Firebase
This post hasn't been updated for 5 years
Firebase là một service khá nổi tiếng nên có lẽ mình sẽ không cần phải giới thiệu nữa. Firebase cung cấp khá nhiều dịch vụ Backend mạnh mẽ. Bài viết hôm nay, mình xin được giới thiệu một chức năng nhỏ của Firebase, là Custom token to Authentication.
Đặt vấn đề
Bạn xây dựng một ứng dụng Rails, muốn sử dụng dịch vụ Realtime Database hoặc Cloud Firestore để cung cấp dịch vụ chat cho user thay vì mở websocket sẽ rất tốn tài nguyên cho server.
Để được vào Room chat thì chắc chắn rồi, user sẽ phải đăng nhập. Firebase cung cấp dịch vụ Authentication để xác thực user với Firebase (https://firebase.google.com/docs/auth/), nhưng hệ thống của bạn đã bắt buộc đăng nhập trước đó, không lẽ muốn vào chat thì phải đăng nhập thêm 1 lần nữa để xác thực với Firebase? Giải quyết vấn đề này, Firebase cung cấp cho bạn 2 giải pháp: Một là bỏ qua xác thực user, tuy nhiên cách này quá nguy hiểm; Hai là phía Backend sẽ xử lý gửi custom token cho Firebase để xác thực user.
Firebase cho phép bạn toàn quyền kiểm soát việc xác thực user với Firebase sử dụng JWT. Bạn sẽ tạo ra một token trong ứng dụng của bạn, gửi nó cho client và client sẽ dùng token này để xác thực với Firebase thông qua phương thức signInWithCustomToken()
Trước khi bắt đầu
- Giả sử bạn đã có một hệ thống trong đó có chức năng đăng nhập và đang xây dựng chức năng ChatRoom.
- Giả sử bạn cũng đã tạo được một Firebase Project và đang có ý định sử dụng Realtime Database để xây dựng chức năng ChatRoom của bạn.
Đầu tiên, bạn truy cập vào Console của Firebase tải JSON private key file của Project về máy (Project Overview > Project Settings > Service Account > Generate new private key)
Không public file này, vì nó chứa thông tin để đăng nhập vào Firebase Project của bạn.
Tạo token sử dụng JWT
Vì Ruby là ngôn ngữ không được hỗ trợ Firebase Admin SDK chính thức, nên việc tạo custom token sẽ được làm thủ công.
Tạo ra một JWT bao gồm các thông tin bắt buộc sau:
Key | Viết tắt của | Ý nghĩa |
---|---|---|
alg | Algorithm | Giá trị = "RS256" |
iss | Issuer | Địa chỉ email của tài khoản chủ Project |
sub | Subject | Địa chỉ email của tài khoản chủ Project |
aud | Audience | Giá trị = "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat | Issued-at time | Thời gian hiện tại (in seconds since the UNIX epoch) |
exp | Expiration time | Thời gian hết hạn (in seconds since the UNIX epoch), tối đa 3600s kể từ Issued-at time |
uid | Mã định danh duy nhất của user trong ứng dụng Rails của bạn, chuỗi string 1-36 ký tự | |
claims (optional) |
Có 1 lưu ý là mặc dù config thời gian hết hạn của Token là 1h, nhưng khi Client sử dụng phương thức signInWithCustomToken()
nhưng họ vẫn sẽ được giữ phiên làm việc cho đến khi người dùng đăng xuất mà không cần phải refresh lại để lấy token mới.
Với Rails, bạn có thể tạo 1 file Lib hoặc Service để generate token theo yêu cầu của Firebase như sau:
class FirebaseAdmin
def initialize
@private_key_json = File.open(ENV["FIREBASE_KEY_FILE_PATH"]).read
@firebase_email = ENV["FIREBASE_EMAIL"]
end
def create_custom_token uid
now_seconds = Time.now.to_i
payload = {
iss: firebase_email,
sub: firebase_email,
aud: "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
iat: now_seconds,
exp: now_seconds + 3600,
uid: uid,
claims: {}
}
JWT.encode payload, private_key, "RS256"
end
private
attr_reader :private_key_json, :firebase_email
def firebase_info
JSON.parse(private_key_json, symbolize_names: true)
end
def private_key
OpenSSL::PKey::RSA.new firebase_info[:private_key]
end
end
Việc xác thực user với Firebase thế là xong, việc cuối cùng là bạn cầm cái key tương ứng với user trả về cho client.
class Api::V1::Firebase::AuthenticationsController < Api::V1::BaseController
before_action :doorkeeper_authorize!, only: :show
def show
jwt_token = FirebaseAdmin.new.create_custom_token current_user.id
render json: {token: jwt_token}
end
end
Client dùng key này xác thực với Firebase và có thể sử dụng các dịch vụ của Firebase như Reatime Database, ....
Bài viết của mình đã giới thiệu với các bạn cách xác thực user của hệ thống với Firebase sử dụng Rails app. Chúc các bạn thành công!
Tham khảo: https://firebase.google.com/docs/auth/admin/create-custom-tokens
All Rights Reserved