diff --git a/app/controllers/oauth_controller.rb b/app/controllers/oauth_controller.rb index 00549212d..f2efc4243 100644 --- a/app/controllers/oauth_controller.rb +++ b/app/controllers/oauth_controller.rb @@ -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 diff --git a/app/models/oauth.rb b/app/models/oauth.rb index 5b369be68..23f5f835c 100644 --- a/app/models/oauth.rb +++ b/app/models/oauth.rb @@ -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 diff --git a/config/routes.rb b/config/routes.rb index b4a9efacc..7b6830322 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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' diff --git a/db/migrate/20181121064652_create_oauth.rb b/db/migrate/20181122034752_add_user_id_to_oauths.rb similarity index 64% rename from db/migrate/20181121064652_create_oauth.rb rename to db/migrate/20181122034752_add_user_id_to_oauths.rb index b54d00d6d..4e2ed5bc4 100644 --- a/db/migrate/20181121064652_create_oauth.rb +++ b/db/migrate/20181122034752_add_user_id_to_oauths.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index fffb44df3..71bd540bc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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"