Li Yafei
A senior Ruby on Rails developer
By WinDy
2015.4.18
# configuration of doorkeeper
Doorkeeper.configure do
orm :active_record
resource_owner_authenticator do
if Doorkeeper::Application.where(uid: params[:client_id]).first.try(:name) == 'forum'
session[:previous_url] = ENV['FORUM']
end
current_user || redirect_to(new_user_session_url)
current_user
end
admin_authenticator do
current_user && current_user.has_role?(:admin) || redirect_to(root_path)
end
skip_authorization do |resource_owner, client|
client.name == 'forum'
end
end
# Api basement controller
class Api::ApiController < ApplicationController
private
# Find the user that owns the access token
def current_resource_owner
User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
end
end
# api impelement : user
class Api::UsersController < Api::ApiController
before_action :doorkeeper_authorize!
def show
@user = current_resource_owner
end
end
# json.jbuilder
json.extract! @user, :id, :email, :nickname
json.avatar_url image_path(@user.avatar_url)
# route
Rails.application.routes.draw do
use_doorkeeper
namespace :api do
resource :user, only: [:show]
end
end
# a client strategy
module OmniAuth
module Strategies
class Jiaoluo < OmniAuth::Strategies::OAuth2
SITE = CONFIG['JIAOLUO_SITE']
option :name, "jiaoluo"
option :client_options, {
:site => SITE,
:authorize_url => "#{SITE}/oauth/authorize",
:token_url => "#{SITE}/oauth/token",
}
uid{ raw_info['id'] }
info do
{
:name => raw_info['nickname'],
:email => raw_info['email'],
:avatar => raw_info['avatar_url'],
}
end
extra do
{
'raw_info' => raw_info
}
end
def raw_info
@raw_info ||= access_token.get('/api/user').parsed
end
end
end
end
# jiaoluo middleware
Rails.application.config.middleware.use OmniAuth::Builder do
provider :developer unless Rails.env.production?
provider :jiaoluo, CONFIG['JIAOLUO_KEY'], CONFIG['JIAOLUO_SECRET']
end
# route
Rails.application.routes.draw do
get '/auth/:provider/callback', to: 'sessions#create_from_omniauth'
end
# session controller
class SessionsController < ApplicationController
def create_from_omniauth
omniauth = request.env["omniauth.auth"]
@user = User.where(jiaoluo_uid: omniauth['uid'].to_s).first
if @user
@user.update_from_omniauth(omniauth)
else
@user = User.create_from_omniauth(omniauth)
end
login_as @user
#remember_me
redirect_back_or_default root_url
end
end
# user model
class User < ActiveRecord::Base
def self.create_from_omniauth(omniauth)
user = User.new(
username: omniauth['info']['name'],
jiaoluo_uid: omniauth['uid'],
name: omniauth['info']['name'],
email: omniauth['info']['email'],
avatar: omniauth['info']['avatar']
)
user.save!
user
end
end
# session logout
class User < ActiveRecord::Base
def destroy
logout
if CONFIG['JIAOLUO_SITE'].present?
redirect_to CONFIG['JIAOLUO_SITE'] + '/logout'
else
redirect_to root_path
end
end
end
# config YML
JIAOLUO_KEY: cefcafaf6d7cf962dd610a5ea99be16fb15113ddd1d713a91a12fc76da51d9af
JIAOLUO_SECRET: b8d26c6c9b63199cc31e7e8131a278add3ac345567151f981ad1fac305ad445b
JIAOLUO_SITE: http://jiaoluo.it
# redis resque form
class ResqueForum
# create topic in Jiaoluo forum
def self.push(course_type, title, body, user)
return if Rails.env == 'test'
user = {
uid: user.id,
name: user.nickname,
email: user.email,
avatar_url: ActionController::Base.helpers.asset_path(user.avatar_url),
}
if ENV['REDIS_HOST'].present?
@@redis ||= Redis.new(host: ENV['REDIS_HOST'],
port: ENV['REDIS_PORT'],
db: ENV['REDIS_DB'],
driver: :hiredis)
args = {
class: ENV['REDIS_CLASS_JOB'],
args: [course_type, title, body, user],
}.to_json
queues = ENV['REDIS_QUEUE'].split(':')[0..1].join(':')
queue_name = ENV['REDIS_QUEUE'].split(':')[-1]
queues += 's'
@@redis.sadd(queues, queue_name)
@@redis.rpush(ENV['REDIS_QUEUE'], args)
end
end
end
By Li Yafei
A tutor that teaches you how to integrate a community website into Rails APP with Doorkeeper and Omniauth2