設計使用者驗證,製作 API 內的 current_user

這裡會先建立一個 Api access token 的 model,是比較基本的作法而已,實際的作法通常還會加上

  • Log 記錄
  • Expire 有效期限

這邊先不考慮上述的狀況,只把 api access token 當作能夠確認身份的令牌而已,所以要關聯 user 來做到透過 api endpoint 的請求能夠確認身份

建立 model rails g model api_access_token user_id:integer key:string

class ApiAccessToken < ApplicationRecord
  belongs_to :user

  before_create :generate_keys

  private

  def generate_keys
    begin
      self.key = SecureRandom.urlsafe_base64(30).tr('_-', 'xx')
    end while ApiAccessToken.where(key: key).any?
  end
end

確認 api access token 被建立後會建立一個隨機的密鑰,因為這樣的作法沒有避免碰撞,也就是生出一樣的 key ,所以額外做了一個簡單的判斷,建立直到沒有重複的 key 為止。

建立 auth 資料夾

mkdir app/api/api_v0/auth

實做 middleware 讓我們在中間層先處理用戶發進來的請求,去判斷是否要將用戶數據提前塞到 object 裡面。

touch app/api/api_v0/auth/middleware.rb

module ApiV0
  module Auth
    class Middleware < Grape::Middleware::Base
      def before
        if auth_provided?
          @env["api_v0.token"] = Authenticator.new(request, params).authenticate!
          @env["api_v0.user"] ||= @env["api_v0.token"].try(:user)
        end
      end

      def request
        @request ||= ::Grape::Request.new(env)
      end

      def params
        @params ||= request.params
      end

      def auth_provided?
        params[:access_key].present?
      end
    end
  end
end

依照 middleware 規劃,實做 authenticator.rb

touch app/api/api_v0/auth/authenticator.rb

module ApiV0
  module Auth
    class Authenticator
      def initialize(request, params)
        @request = request
        @params  = params
      end

      def authenticate!
        check_token!
        token
      end

      def token
        @token = ApiAccessToken.joins(:user).where(key: @params[:access_key]).first
      end

      def check_token!
        return @params[:access_key] unless token
      end
    end
  end
end

api/api_v0/base.rb 中加上

module ApiV0
  class Base < Grape::API
    #...
    use ApiV0::Auth::Middleware
    #...
  end
end
Copyright © NicLin 2019 all right reserved,powered by Gitbook該頁面生成時間: 2019-04-09 10:00:37

results matching ""

    No results matching ""