H5及web页⾯授权登录流程
PC端扫码登录流程:
为什么要登录:
如果⽤户在客户端中访问第三⽅⽹页,可以通过⽹页授权机制,来获取⽤户基本信息,进⽽实现业务逻辑。拥有庞⼤且稳定活跃的⽤户基数,直接将我们的app接⼊到的⽣态可以免去复杂的新⽤户注册流程,使⽤户体验更良好。
登录的⼏种情况:
PC端:
PC端浏览器 -> 直接调⽤授权(不扫码,使⽤服务号的appid和appsecret)
PC端其他浏览器 -> 跳转的扫码登录页⾯(需要扫码,使⽤开放平台注册的PC应⽤appid和appsecret)移动端:
客户端打开 -> 直接调⽤授权(不扫码,使⽤服务号的appid和appsecret)
其他⼿机浏览器打开 -> 跳转的扫码登录页⾯(需要扫码,使⽤开放平台注册的PC应⽤appid和appsecret)
区分是否是PC环境的⽅法:
判断是PC环境还是移动环境是为了相应切换应⽤的布局,⽬前采⽤css媒体查询来做判断:
/* 屏幕宽度⼩于等于1070像素时识别为移动端(1070像素是使推荐页常⽤情报站栏不现实滚动条的最⼩宽度) */
@media screen and (max-width: 1070px) {
/* 移动端布局css样式 */
}
/* 屏幕宽度⼤于1071像素识别为PC端 */
@media screen and (min-width: 1071px) {
/* PC端布局样式 */
}
这⾥⽬前的设计是将判断UI样式和判断登录逻辑区分开的,两个功能分别独⽴判断
区分登录的⼏种情况的⽅法:
前端在登录时获取⽤户设备信息(userAgent)
let UA = LocaleLowerCase()
// UA的格式可能因设备不同⽽采⽤不同的⼤⼩写格式这⾥我们先统⼀为⼩写⽅便下⼀步判断
UA.indexOf("micromessenger") != -1
// 通过indexOf⽅法来判断字符串⾥是否有要查询的字段
前端操作
1 获取code(此步骤由前端完成)
⾸先要在开放平台⾥申请创建⼀个web应⽤,填写完基本信息之后提交审核,最长7个⼯作⽇,⼀
般两天就能下来。审核通过以后可以得到web应⽤的AppID和AppSecret,稍后请求登录的⼆维码。
在得到web应⽤的AppID以后前端需要配置请求登录⼆维码的url:
// 前端使⽤appid和回调域名来获取登陆⼆维码
place(
"open.weixin.qq/connect/qrconnect?" +
"appid=" + APP_id + "&" +
"redirect_uri=" + encodeURIComponent('wx.digitwonder') + "&" +
"scope=snsapi_login#wechat_redirect" )
这个配置中AppID字段是向后台传开放平台的web应⽤AppID,回调地址也是在开放平台注册时留的地址,⽽且这个回调地址的uri需要经过encode编码加密以后拼接到请求的。'scope'字段表⽰请求的作⽤域,扫码登录时scope字段固定
写'snsapi_login'。将这个地址拼接好以后就可以将路由定向到的⼆维码页⾯了。
参数说明
参数是否
必须
说明
appid 是应⽤唯⼀标识(前⾯认证⽹页应⽤中获得)redirect_uri
是重定向地址,需要进⾏UrlEncode (前⾯认证⽹页应⽤中获得)response_type
是填code scope
是应⽤授权作⽤域,拥有多个作⽤域⽤逗号(,)分隔,⽹页应⽤⽬前仅填写snsapi_login 即可state 是⽤于保持请求和回调的状态,授权请求后原样带回给第三⽅。该参数可⽤于防⽌csrf 攻击(跨站请求伪造攻击),建
议第三⽅带上该参数,可设置为简单的随机数加session 进⾏校验
参数是否必须说明在页⾯定位到⼆维码页⾯以后扫码确认,页⾯会被定向到之前配置的回调页⾯地址并且将请求来的code 拼接到url 上⼀并返回,我们在确认登陆以后回到url 拼接有code 的页⾯获取到code 之后向后台发送登陆请求。
// 声明变量flag ⽤来存储回调页⾯的code 信息
let flag = flag.split("&")[0];
// 重定向该页⾯的路由(清除url 中的code ) - 避免发送code 请求
this.$place({
path: "/login",
query: {
redirect: this.$direct
}
});
url: "/biz/login/wx", // 后台接收code 的接⼝
method: "POST", // 使⽤HTTP 的POST ⽅法传回code
data: {
code: flag // 将页⾯存储code 的flag 变量以code 字段传给后台
// 此处区分登录⽅式的字段待定
}
}).then(res => {
// 前端本地获取⽤户信息后的⽅法
})
后端操作
接⼝结构
接⼝: (post)/biz/login/wx
参数: browser(取值为 wx,other)
返回数据(json):
// 登录成功时返回
{
"code": 1,
"msg": "SUCCESS",
"data": {
"nick": "⽤户昵称",
"role_id": 2,
"mobile": "⼿机号",
"avatar": "⽤户头像",
"birthday": 1578909982972,
"gender": 2,
"location": "地区",
"summary": "⽤户简介",
"eval": true,
"status": "Complete",
"last_login": 1578909982972,
"id": "id",
"create_time": 1571755690000,
"update_time": 1578885503000
}
}
// 登录失败时返回
{
"code": 0,
"msg": "FAILURE"
}
1 获取access_token
收到登录请求后⾸先通过code 向服务器换取access_token 。
根据不同的浏览器类型使⽤相应的appid 和secret
/
/ 请求url(Get)
api.weixin.qq/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
参数说明
参数是否必须说明
appid是应⽤唯⼀标识
secret是应⽤密钥AppSecret
code是填写第⼀步获取的code参数
grant_type是填authorization_code
浏览器登录时使⽤appid和secret, 其他浏览器登录使⽤⽹站应⽤appid和secret 返回数据说明
名称类型说明
access_token String access_token
expires_in int access_token有效时间
refresh_token String refresh_token
openid String open_id
scope String授权作⽤域
当获取数据出错时,返回结果中包含"errCode"字段, 登录失败
2 拉取⽤户信息
通过第⼀步中获取到的access_token和openid拉取user_info
// 请求url(Get)
api.weixin.qq/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
参数说明
参数是否必须说明
access_token是上⼀步中获取到的access_token
openid是⽤户唯⼀标识,上⼀步中获取到的openid
返回数据说明
名称类型说明
openid String open_id
unionid String union_id
nickname String⽤户昵称
sex int性别
province String省
city String城市
country String国家
headimgurl String⽤户头像
为什么换不了头像privilege Array⽤户权限
当获取数据出错时,返回结果中包含"errCode"字段, 登录失败
3 ⽣成或获取本地⽤户
通过union_id获取第三⽅平台账号
第三⽅平台账号存在时通过uid获取⽤户数据,否则继续
使⽤登录的账户需要将其⽤户数据转换成本地⽤户并存储
添加⽤户缓存
创建或更新⽤户Auth数据
更新ES(UserIndex)
创建⽤户媒体
4 返回⽤户数据
将⽤户数据返回到前台
发布评论