wuyuedefeng / blogs

博客文章在issue中
5 stars 0 forks source link

Rails使用doorkeeper引入OAuth2 #54

Open wuyuedefeng opened 4 years ago

wuyuedefeng commented 4 years ago

安装

$ gem 'doorkeeper'
$ bundle exec rails generate doorkeeper:install
$ bundle exec rails generate doorkeeper:migration
# Using PostgreSQL UUIDs as primary keys with Doorkeeper
# $ rails g migration enable_pgcrypto_extension

流程说明

  +--------+                               +---------------+
 |        |--(A)- Authorization Request ->|   Resource    |
 |        |                               |     Owner     |
 |        |<-(B)-- Authorization Grant ---|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(C)-- Authorization Grant -->| Authorization |
 | Client |                               |     Server    |
 |        |<-(D)----- Access Token -------|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(E)----- Access Token ------>|    Resource   |
 |        |                               |     Server    |
 |        |<-(F)--- Protected Resource ---|               |
 +--------+

grant_type = password

直接将用户的emailpassword, grant_type, client_id, client_secret参数 post -> http://localhost:3000/oauth/token 获取用户的access_tokenrefresh_token, expires_in, token_type等信息

grant_type = authorization_code

  1. 创建application配置client_idclient_secretredirect_uri
  2. 用户跳转到个人页面,点击授权按钮 访问/oauth/authorize?client_id=${ clientId }&redirect_uri=${ redirect_uri }&response_type=code&scope=read 获取grant code
  3. 重定向到配置application的redirect_uri并携带code: 格式 ${ redirect_uri }?code=xxxxxx
  4. 重定向的页面给服务器,服务器通过client_idclient_secret, grant_type = authorization_code, redirect_uri, code参数,post -> http://localhost:3000/oauth/token 获取用户的access_tokenrefresh_token, expires_in, token_type等信息

grant_type = client_credentials

有时候api是给指定用户用的,不用登录就可以知道是谁在用,这时候就可以client_credentials,这个获取的access_token是和应用绑定的。

client_id, client_secret, grant_type参数 post -> http://localhost:3000/oauth/token

所以该方法,无法获取用户信息获取到的token只能查询到application(及哪个商户调用的)

备注: 上面方法可以在header添加 Basic Authorization, 格式: client_id:client_secret,然后参数只需要传client_id即可

About Docs


https://ruby-china.org/topics/14656 https://github.com/tianlu1677/tianlu1677.github.io/wiki/Oauth2 https://www.open-open.com/doc/92f1beb802184b41b3ecfa0eeccfd5f8.html https://naturaily.com/blog/api-authentication-devise-doorkeeper-setup https://www.coder.work/article/2052669

wuyuedefeng commented 4 years ago

rails api mode config/initializers/doorkeeper.rb

Doorkeeper.configure do
  # Change the ORM that doorkeeper will use (requires ORM extensions installed).
  # Check the list of supported ORMs here: https://github.com/doorkeeper-gem/doorkeeper#orms
  orm :active_record

  # This block will be called to check whether the resource owner is authenticated or not.
  # 认证 Resource Owner 的方法,直接接 Devise -> https://www.open-open.com/doc/92f1beb802184b41b3ecfa0eeccfd5f8.html
  resource_owner_authenticator do
    #raise "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}"
    current_user || warden.authenticate!(scope: :user)
    # Put your resource owner authentication logic here.
    # Example implementation:
    #   User.find_by(id: session[:user_id]) || redirect_to(new_user_session_url)
  end

  #admin_authenticator do |routes|
  #  User.first
  #end

  resource_owner_from_credentials do |_routes|
    current_user || User.authenticate(params[:email], params[:password])
  end

  #在某些情况下,你可能想让申请自动通过, 以便用户跳过授权步骤。 例如,处理一个受信任的应用程序。
  skip_authorization do
    current_user || warden.authenticate!(scope: :user)
  end

  grant_flows %w(authorization_code client_credentials password)

  use_refresh_token

  api_only
  base_controller 'ApplicationController'
end
wuyuedefeng commented 1 year ago

Rails Github 授权登录 https://github.com/wuyuedefeng/blogs/issues/84