微信网页授权登录 OAuth2.0
如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。
-- 引自 微信开放文档
要接入微信授权登录,先确保有一个公众号,获取微信信息,得有一个主体。开发前,需要提前准备好网页域名的配置,在公众平台官网中的 “开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息” 的配置项中添加。需要注意的是,此处填写的是域名,而非地址,去掉 http:// 类似的协议头;域名配置只需要填写一级域名,如 www.xx.com,而非 www.xx.com/xxx/xx.html。
接下来看看微信的流程
(1)引导用户进入授权页面同意授权,获取code;(跳转到微信服务页面,然后微信服务器会将参数放在开发者指定的返回地址中)
(2)通过code换取网页授权access_token;(拿到 code 后,向微信服务端换取access_token )
(3)拉取用户信息(静默授权仅能拿到用户的 OpenID,手动授权能获取到 UnionID、昵称头像等)
详细步骤
1. 获取code。引导关注者打开如下页面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
其中参数如下:
appid | 公众号的唯一标识 |
redirect_uri | 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理 |
response_type | 返回类型,请填写code |
scope | 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 ) |
state | 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 |
#wechat_redirect | 无论直接打开还是做页面302重定向时候,必须带此参数 |
两种 scope 的区别在于,snsapi_base 属于静默授权,会跳转到回调页,对于用户是无感知的,只能获取用户的 OpenID;snsapi_userinfo 属于手动授权,会弹出一个授权弹框,用户点击确认后,就会跳转到回调页,并携带必要的数据。需要指出的是,若近期进行过手动授权,或者关注公众号的用户通过公众号进入,会采取静默的方式授权。
授权后,页面跳转至 redirect_uri/?code=CODE&state=STATE。redirect_uri 应当使用https链接来确保授权code的安全性。通常,我们在一个页面上完成网页的授权登录,因此可以通过 STATE 来添加标识符,页面首次加载时,进入授权流程,在跳转 url 中的STATE 中增加一个参数,当从微信页面再次返回时,读取到此参数,即可判断已经完成了步骤1,即将进入步骤2 。
2. 通过code换取网页授权access_token 。拿到 code 后,请求以下接口获取 access_token,若网页授权的作用域为snsapi_base,则此步骤即可拿到 OpenID,流程到此为止。此步骤的请求,需要放在后端请求,公众号的secret和获取到的access_token安全级别都非常高,必须只保存在服务器,不可在前端操作,且前端操作会导致跨域。
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
相关代码:
function redirectWX(type){ // type 标识符,判断为是否进行手动授权 var url = location.href url = url.replace(/code=([^\&]*)(\&|$)/, '').replace(/state=([^\&]*)(\&|$)/, '') var REDIRECT_URI = encodeURIComponent(url) var APPID = 'wx3e*********' var SCOPE = 'snsapi_base' var STATE = 'silent' if(type){ SCOPE = 'snsapi_userinfo' STATE = 'confirm' } var redirectUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + APPID + '&redirect_uri=' + REDIRECT_URI + '&response_type=code&scope=' + SCOPE + '&state=' + STATE + '#wechat_redirect' location.replace(redirectUrl) }