Skip to content

Instantly share code, notes, and snippets.

@mimosa
Created June 27, 2016 04:17
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mimosa/502d1e60eb765e6d655d8c1911904d2e to your computer and use it in GitHub Desktop.
Save mimosa/502d1e60eb765e6d655d8c1911904d2e to your computer and use it in GitHub Desktop.
微信扫码登录。
  1. 判定是否在微信中打开
def wechat?
    request.user_agent =~ /MicroMessenger/i 
end
  1. 分别调用 微信网页扫码公众号授权
def wechat_cli
    @wechat_cli ||= if wechat?
       WechatMp.new('key', 'secret') # 微信公众号
    else
       Wechat.new('key', 'secret') # 微信扫码
    end 
end
  1. 跳转页
redirect wechat_cli.authorize_uri, permanent: true
  1. 回调处理
unauthorized('未获得授权') if params[:code].blank?
token = wechat_cli.token(params[:code]) 
if token && token['unionid']
    # 通过 token['unionid'] 查询是否已存在
    # 通过 wechat_cli.userinfo(token) 获取用户信息
end
# -*- encoding: utf-8 -*-
class RestCli
def initialize(endpoint)
connection.url_prefix = endpoint
end
def get(path, params=nil, headers = nil)
self.request(:get, path, params, headers)
end
def post(path, params=nil, headers = nil)
self.request(:post, path, params, headers)
end
def request(method, url, body, headers=nil)
parser connection.send(method, url, body, headers)
rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e
puts '_'*88
end
def connection
@connection ||= Faraday.new( ssl: { verify: false } ) do |conn|
conn.request :multipart
conn.request :url_encoded
conn.request :retry, max: 2, interval: 0.05,
interval_randomness: 0.5, backoff_factor: 2,
exceptions: [Faraday::TimeoutError, Timeout::Error]
conn.response :logger
conn.adapter :typhoeus
conn.options.open_timeout = 10
conn.options.timeout = 10
end
end
def parser(resp)
MultiJson.load(resp.body) rescue nil if resp.status.between?(200,201)
end
end
# -*- encoding: utf-8 -*-
class Wechat < RestCli # 微信网页扫码
def initialize(key, secret, endpoint='https://api.weixin.qq.com')
@params = {
appid: key,
secret: secret
}
connection.url_prefix = endpoint
end
def token(code)
resp = get('/sns/oauth2/access_token', @params.merge(code: code, grant_type: 'authorization_code'))
resp.as_json(only: ['unionid', 'access_token', 'openid'])
end
def userinfo(params)
info = {}
resp = get('/sns/userinfo', params)
if resp && resp['nickname']
info = resp.as_json(only: ['nickname', 'headimgurl'])
info = {
username: info['nickname'],
avatar_url: (info['headimgurl'] + '/avatar.jpg'),
role: :user
}
end
info
end
def authorize_uri
'https://open.weixin.qq.com/connect/qrconnect?' + query_string + '#wechat_redirect'
end
private
def query_string
{
appid: @params[:appid],
redirect_uri: '回调URL',
response_type: 'code',
scope: 'snsapi_login',
state: 'qrconnect'
}.to_query
end
end
# -*- encoding: utf-8 -*-
class WechatMp < Wechat # 微信公众号
def authorize_uri
'https://open.weixin.qq.com/connect/oauth2/authorize?' + query_string + '#wechat_redirect'
end
private
def query_string
{
appid: @params[:appid],
redirect_uri: '回调URL',
response_type: 'code',
scope: 'snsapi_userinfo',
state: 'oauth2'
}.to_query
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment