Conflicts: db/schema.rbdev_toschina
| @@ -1,7 +1,13 @@ | |||
| #encoding: utf-8 | |||
| class OauthController < ApplicationController | |||
| include ApplicationHelper | |||
| before_filter :user_setup | |||
| before_filter :require_login, only: [:authorize, :token] | |||
| before_filter :require_login, only: [:authorize,:token] | |||
| skip_before_filter :verify_authenticity_token, only: [:token] | |||
| # 客户端申请认证的URI,包含以下参数: | |||
| # | |||
| @@ -55,8 +61,7 @@ class OauthController < ApplicationController | |||
| client_id = "88d893c5a345313e7b8c6fcf23d3d024ee08d5e41ce120c3448b6eea77d8de30" | |||
| client_secret = "e9240cc5fc913741db5aea93f2986a8ea0631bb67f7c00e41e491b95d9619e64" | |||
| redirect_uri = "http://localhost:3000/oauth/cb" | |||
| url = "http://127.0.0.1:3000/oauth/token?grant_type=authorization_code&code=#{params['code']}" | |||
| +"&redirect_uri=#{redirect_uri}&client_id=#{client_id}&client_secret=#{client_secret}" | |||
| url = "http://127.0.0.1:3000/oauth/token?grant_type=authorization_code&code=#{params['code']}&redirect_uri=#{redirect_uri}&client_id=#{client_id}&client_secret=#{client_secret}" | |||
| render text: url | |||
| end | |||
| @@ -81,6 +86,8 @@ class OauthController < ApplicationController | |||
| # refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。 | |||
| # scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。 | |||
| def token | |||
| res = {} | |||
| if params[:grant_type] == 'authorization_code' | |||
| raise "code必传" unless params["code"] | |||
| @@ -89,15 +96,16 @@ class OauthController < ApplicationController | |||
| raise "code错误或已超时" unless Oauth.code_valid?(params["code"]) | |||
| oauth = Oauth.auth(params["code"], params["client_id"], params["client_secret"]) | |||
| oauth = Oauth.auth_code(params["code"], params["client_id"], params["client_secret"]) | |||
| raise "认证不通过" unless oauth | |||
| ## 生成 token | |||
| # | |||
| oauth.gen_token(User.current.id) | |||
| oauth.reload | |||
| { | |||
| res = { | |||
| access_token: oauth.access_token, | |||
| token_type: 'bearer', | |||
| expires_in: oauth.token_expires_in, | |||
| @@ -106,6 +114,25 @@ class OauthController < ApplicationController | |||
| end | |||
| render json: res.to_json | |||
| end | |||
| def get_userinfo | |||
| user = Oauth.auth(params["access_token"]) | |||
| user_info = {} | |||
| if user | |||
| user_info = { | |||
| token: user.id, | |||
| login: user.login, | |||
| avatar_url: "/images/"+url_to_avatar(user), | |||
| name: user.show_name, | |||
| email: user.mail | |||
| } | |||
| end | |||
| render json: user_info.to_json | |||
| end | |||
| @@ -1,7 +1,10 @@ | |||
| require 'base64' | |||
| class Oauth < ActiveRecord::Base | |||
| attr_accessible :client_id, :client_secret, :redirect_uri | |||
| attr_accessible :client_id, :client_secret, :redirect_uri, :access_token, | |||
| :refresh_token, :token_created_at,:token_expires_in, :user_id | |||
| belongs_to :user | |||
| def gen_code | |||
| @@ -10,5 +13,43 @@ class Oauth < ActiveRecord::Base | |||
| code | |||
| end | |||
| def gen_token(user_id) | |||
| access_token = Digest::MD5.hexdigest "#{Time.now}-#{Random.new_seed}" | |||
| refresh_token = Digest::MD5.hexdigest "#{Random.new_seed}-#{Time.now}-#{Random.new_seed}" | |||
| self.update_attributes(access_token: access_token, | |||
| refresh_token: refresh_token, | |||
| token_created_at: Time.now.to_i, | |||
| token_expires_in: Time.now.to_i + 24*60*60, | |||
| user_id: user_id | |||
| ) | |||
| end | |||
| def self.code_valid?(code) | |||
| # 1. 是否存在 | |||
| oauth = Oauth.where(code: code).order("ID desc").first | |||
| return false unless oauth | |||
| # 2. 是否超过10分钟 | |||
| return false if Time.now.to_i - oauth.created_at.to_i > 10*60 | |||
| # 3. 是否有使用过 | |||
| return false if oauth.access_token.present? | |||
| return true | |||
| end | |||
| def self.auth_code(code, client_id, client_secret) | |||
| Oauth.where(code: code, client_id: client_id, client_secret: client_secret).order('id desc').first | |||
| end | |||
| def self.auth(access_token) | |||
| oauth = self.find_by_access_token(access_token) | |||
| return nil unless oauth | |||
| oauth.user | |||
| end | |||
| end | |||
| @@ -562,6 +562,7 @@ RedmineApp::Application.routes.draw do | |||
| match 'oauth/authorize', to: 'oauth#authorize', :via => [:get, :post] | |||
| match 'oauth/token', to: 'oauth#token', :via => :post | |||
| match 'oauth/cb', to: 'oauth#test_callback', :via => :get | |||
| match 'oauth/userinfo', to: 'oauth#get_userinfo', :via => :get | |||
| # boards | |||
| match 'boards/:board_id/topics/new', :to => 'messages#new', :via => [:get, :post], :as => 'new_board_message' | |||
| @@ -1,6 +1,7 @@ | |||
| class CreateOauth < ActiveRecord::Migration | |||
| class AddUserIdToOauths < ActiveRecord::Migration | |||
| def change | |||
| create_table :oauth do |t| | |||
| create_table :oauths do |t| | |||
| t.string :client_id | |||
| t.string :client_secret | |||
| t.string :code | |||
| @@ -14,5 +15,10 @@ class CreateOauth < ActiveRecord::Migration | |||
| t.timestamps | |||
| end | |||
| add_column :oauths, :user_id, :integer, default: 0 | |||
| add_index :oauths, :user_id | |||
| end | |||
| end | |||
| @@ -11,7 +11,7 @@ | |||
| # | |||
| # It's strongly recommended to check this file into your version control system. | |||
| ActiveRecord::Schema.define(:version => 20181121071704) do | |||
| ActiveRecord::Schema.define(:version => 20181122034752) do | |||
| create_table "activities", :force => true do |t| | |||
| t.integer "act_id", :null => false | |||
| @@ -1539,19 +1539,13 @@ ActiveRecord::Schema.define(:version => 20181121071704) do | |||
| t.string "refresh_token" | |||
| t.integer "token_created_at" | |||
| t.integer "token_expires_in" | |||
| t.datetime "created_at", :null => false | |||
| t.datetime "updated_at", :null => false | |||
| end | |||
| create_table "oauth_configs", :force => true do |t| | |||
| t.string "client_id" | |||
| t.string "client_secret" | |||
| t.string "redirect_uri" | |||
| t.string "scope" | |||
| t.datetime "created_at", :null => false | |||
| t.datetime "updated_at", :null => false | |||
| t.datetime "created_at", :null => false | |||
| t.datetime "updated_at", :null => false | |||
| t.integer "user_id", :default => 0 | |||
| end | |||
| add_index "oauths", ["user_id"], :name => "index_oauths_on_user_id" | |||
| create_table "onclick_times", :force => true do |t| | |||
| t.integer "user_id" | |||
| t.datetime "onclick_time" | |||