Skip to main content

Ruby On Rails

配置Authok

获取应用密钥

你需要如下信息

  • Domain
  • Client ID
  • Client Secret

配置回调URL

配置 Logout URL

安装 AuthOK SDK

安装依赖

gem 'omniauth-authok', '~> 3.0'
gem 'omniauth-rails_csrf_protection', '~> 1.0' # prevents forged authentication requests

初始化 AuthOK 配置

创建 AuthOK的配置文件./config/authok.yml:

./config/authok.yml
development:
authok_domain: YOUR_DOMAIN
authok_client_id: YOUR_CLIENT_ID
authok_client_secret: <YOUR AUTHOK CLIENT SECRET>

初始化./config/initializers/authok.rb文件并配置OmniAuth中间件:

./config/initializers/authok.rb
AUTHOK_CONFIG = Rails.application.config_for(:authok)

Rails.application.config.middleware.use OmniAuth::Builder do
provider(
:authok,
AUTHOK_CONFIG['authok_client_id'],
AUTHOK_CONFIG['authok_client_secret'],
AUTHOK_CONFIG['authok_domain'],
callback_path: '/auth/authok/callback',
authorize_params: {
scope: 'openid profile'
}
)
end

添加 AuthOK 控制器

运行命令rails generate controller authok callback failure logout --skip-assets --skip-helper --skip-routes --skip-template-engine来创建 AuthOK 控制器.

./app/controllers/authok_controller.rb
class AuthokController < ApplicationController
def callback
# OmniAuth stores the informatin returned from AuthOK and the IdP in request.env['omniauth.auth'].
# In this code, you will pull the raw_info supplied from the id_token and assign it to the session.
# Refer to https://github.com/authok/omniauth-authok#authentication-hash for complete information on 'omniauth.auth' contents.
auth_info = request.env['omniauth.auth']
session[:userinfo] = auth_info['extra']['raw_info']

# Redirect to the URL you want after successful auth
redirect_to '/dashboard'
end

def failure
# Handles failed authentication -- Show a failure page (you can also handle with a redirect)
@error_msg = request.params['message']
end

def logout
# you will finish this in a later step
end
end

添加如下路由到./config/routes.rb文件:

./config/routes.rb
Rails.application.routes.draw do
# ..
get '/auth/authok/callback' => 'authok#callback'
get '/auth/failure' => 'authok#failure'
get '/auth/logout' => 'authok#logout'
end

添加登录

用户现在可以通过/auth/authok端点来登录应用:

<!-- 在应用中放入一个登录按钮 -->
<%= button_to '登录', '/auth/authok', method: :post %>

添加注销

./app/controllers/authok_controller.rb
class AuthokController < ApplicationController
# ..
# ..插入以下代码
def logout
reset_session
redirect_to logout_url
end

private
AUTHOK_CONFIG = Rails.application.config_for(:authok)

def logout_url
request_params = {
returnTo: root_url,
client_id: AUTHOK_CONFIG['authok_client_id']
}

URI::HTTPS.build(host: AUTHOK_CONFIG['authok_domain'], path: '/v1/logout', query: to_query(request_params)).to_s
end

def to_query(hash)
hash.map { |k, v| "#{k}=#{CGI.escape(v)}" unless v.nil? }.reject(&:nil?).join('&')
end
end
<!-- 在应用中放入一个注销按钮 -->
<%= button_to '注销', 'auth/logout', method: :get %>

展示用户信息

创建一个文件./app/controllers/concerns/secured.rb:

./app/controllers/concerns/secured.rb
module Secured
extend ActiveSupport::Concern

included do
before_action :logged_in_using_omniauth?
end

def logged_in_using_omniauth?
redirect_to '/' unless session[:userinfo].present?
end
end

在任何需要访问控制器中包含Secured模块:

./app/controllers/dashboard_controller.rb
class DashboardController < ApplicationController
include Secured

def show
# session[:userinfo] 之前已通过 AuthokController#callback 保存
@user = session[:userinfo]
end
end

在前端展示:

./app/views/dashboard/show.html.erb
<div>
<p>用户详情:<%= JSON.pretty_generate(@user[:info])%></p>
<p>完整的用户详情:<%= JSON.pretty_generate(@user[:extra][:raw_info])%></p>
</div>