折翼天使资源社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 23|回复: 0

[文档教程] 微信小程序开发用户授权登录实现教程

[复制链接]

6981

主题

7363

帖子

285

积分

网站编辑

Rank: 8Rank: 8

天使之心
0
注册时间
2013-8-22
发表于 2018-11-23 11:22:32 | 显示全部楼层 |阅读模式
用wx.login获取登录凭证code
  1. {{dataList.username}}
  2. 这个玩家很懒,什么也没留下
  3. {{dataList.title}}
  4.   
复制代码
复制代码
3185851ef7dd4a41bb601d31d4a0c826.png

wx.checkSession

小程序 wx.checkSession 校验登陆态

  • success :接口调用成功,session_key未过期;fail :接口调用失败,session_key已过期;



  • 小程序端 wx.login 获取code 并 wx.request 提交 code 给己方服务器
  • 服务器 提交Appid + appSecret + code 到微信方服务器 获取 session_key & openid
  • 服务器 根据 session_key & openid 生成 3rd_session(微信方提出的基于安全性的考虑,建议开发者不要将openid等关键性信息进行数据传输) 并返回 3rd_session 到小程序端
  • 小程序端 wx.setStorage 存储 3rd_session 在后续用户操作需要凭证时 附带该参数
  • 小程序端 wx.getUserInfo 获取用户信息 + wx.getStorage 获取 3rd_session 数据后,一并 wx.request 提交给己方服务器服务器 SQL 用户数据信息更新
  1. //用户登陆
  2. function userLogin() {
  3. wx.checkSession({
  4. success: function () {
  5. //存在登陆态
  6. },
  7. fail: function () {
  8. //不存在登陆态
  9. onLogin()
  10. }
  11. })
  12. }
  13. function onLogin() {
  14. wx.login({
  15. success: function (res) {
  16. if (res.code) {
  17. //发起网络请求
  18. wx.request({
  19. url: 'Our Server ApiUrl',
  20. data: {
  21. code: res.code
  22. },
  23. success: function (res) {
  24. const self = this
  25. if (逻辑成功) {
  26. //获取到用户凭证 存儲 3rd_session
  27. var json = JSON.parse(res.data.Data)
  28. wx.setStorage({
  29. key: "third_Session",
  30. data: json.third_Session
  31. })
  32. getUserInfo()
  33. }
  34. else {
  35. }
  36. },
  37. fail: function (res) {
  38. }
  39. })
  40. }
  41. },
  42. fail: function (res) {
  43. }
  44. })
  45. }
  46. function getUserInfo() {
  47. wx.getUserInfo({
  48. success: function (res) {
  49. var userInfo = res.userInfo
  50. userInfoSetInSQL(userInfo)
  51. },
  52. fail: function () {
  53. userAccess()
  54. }
  55. })
  56. }
  57. function userInfoSetInSQL(userInfo) {
  58. wx.getStorage({
  59. key: 'third_Session',
  60. success: function (res) {
  61. wx.request({
  62. url: 'Our Server ApiUrl',
  63. data: {
  64. third_Session: res.data,
  65. nickName: userInfo.nickName,
  66. avatarUrl: userInfo.avatarUrl,
  67. gender: userInfo.gender,
  68. province: userInfo.province,
  69. city: userInfo.city,
  70. country: userInfo.country
  71. },
  72. success: function (res) {
  73. if (逻辑成功) {
  74. //SQL更新用户数据成功
  75. }
  76. else {
  77. //SQL更新用户数据失败
  78. }
  79. }
  80. })
  81. }
  82. })
  83. }
复制代码
复制代码
第三方服务器和微信服务器:
注意:session_key是微信服务器生成的针对用户数据进行加密签名的密钥,不应该进行传输到客户端.

生成3rd_session
用于第三方服务器和小程序之间做登录态校验.为了保证安全性,3rd_session应该长度够长,一定有效时间, session_key + openid, key, 为 value, 写入到session存储.

3rd_session写入storage:
后续用户进入小程序,先从storage读取3rd_session
根据请求,在session存储中查找合法的session_key和openid
  1. App({
  2. onLaunch: function() {
  3. wx.login({
  4. success: function(res) {
  5. var code = res.code;
  6. if (code) {
  7. console.log('获取用户登录凭证:' + code);
  8. } else {
  9. console.log('获取用户登录态失败:' + res.errMsg);
  10. }
  11. }
  12. });
  13. }
  14. })
复制代码
复制代码
唯一标识(openid)和会话密钥(session_key)
3185851ef7dd4a41bb601d31d4a0c826.png

wx.checkSession

检测当前用户登录态是否有效
  1. wx.checkSession({
  2. success: function(){
  3. //session 未过期,并且在本生命周期一直有效
  4. },
  5. fail: function(){
  6. //登录态过期
  7. wx.login() //重新登录
  8. ....
  9. }
  10. })
复制代码
复制代码
服务端处理逻辑
  1. wx.checkSession({
  2. success:function(res){
  3. //session_key未过期
  4. },
  5. fail:(res=>{
  6. // session_key已过期
  7. // 进行登录操作
  8. wx.login({
  9. success: function(res) {
  10. const url = '接口地址' //本次项目中是从后台获取session_key的接口,可能流程不同,会有相应的变化
  11. const data = {
  12. //你要传的数据
  13. }
  14. wepy.request({
  15. url: url,
  16. method: 'POST',
  17. data: data,
  18. }).then(res=>{
  19. if(res.data.code == 0){
  20. //拿到的openid和session_key存到缓存中
  21. //调用换取用户id接口[需求不同,可能接口会有相应的变化]
  22. const url = '获取用户id的接口'
  23. const data = {'要传的数据'}
  24. wepy.request({
  25. url: url,
  26. method: 'POST',
  27. data: data,
  28. }).then((res)=>{
  29. //该接口设计返回的参数包括换取的用户ID和返回的用户的微信中信息,也就是通过button获取的那个userInfo[我们为了后续的处理,所以后台这块返回用户信息,如果用户还未登录,用户信息,返回是空,反之则有值]
  30. //存储用户ID
  31. wx.setStorage({
  32. key:'userId',
  33. data:'获取到的用户ID'
  34. })
  35. //存储用户信息[userInfo]
  36. wx.setStorage({
  37. key:'userInfo',
  38. data:'获取到的用户信息'
  39. })
  40. })
  41. }
  42. })
  43. }
  44. });
  45. })
  46. })
复制代码
复制代码
  1. onShow(){
  2. //从缓存中获取session_key
  3. let skey = wx.getStorageSync('session_key');
  4. if (!skey) {
  5. //如果session_key不存在,再次执行登录
  6. wx.login({
  7. //该处登录同app.wpy[流程一样]
  8. });
  9. }else{
  10. // session_key存在
  11. }
  12. }
  13. //我们假设这个页面需要获取用户的信息,首先给一个button[open-type设置为getUserInfo],使用这个拿到用户的信息,
  14. getUserInfo(e){
  15. this.userInfo = e.detail.userInfo; //e.detail.userInfo携带的就是用户的个人信息[包括头像、昵称等]
  16. if(e.detail.userInfo){
  17. wx.showToast({
  18. title: '授权成功',
  19. icon: 'success',
  20. duration: 1500
  21. })
  22. //这里做这样的处理,是因为需求需要点击购物车按钮跳转订单待支付页,在没有获取到用户信息之前,跳转购物车的按钮隐藏,获取用户信息按钮显示,反之则返
  23. this.button = 'none'; //获取用户信息button
  24. this.myMenu = 'block'; //跳转待支付订单页
  25. //更新缓存中的用户信息
  26. wx.setStorage({
  27. key:'userInfo',
  28. data:this.userInfo
  29. })
  30. }else if(e.detail.errMsg == 'getUserInfo:fail auth deny'){
  31. wx.showModal({
  32. title: '提示',
  33. content: '若不授权微信登录,则无法使用小程序。点击"授权"按钮并允许使用"用户信息"方可正常使用。',
  34. showCancel:false,
  35. confirmText:'授权',
  36. success:(res=>{
  37. wx.openSetting({
  38. success: (res) => {
  39. }
  40. })
  41. })
  42. })
  43. }
  44. }
复制代码
复制代码
  1. https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
复制代码
复制代码
3185851ef7dd4a41bb601d31d4a0c826.png

对称解密的目标密文为 Base64_Decode(encryptedData)。
对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。
  1. signature = sha1( rawData + session_key )
  2. //最终供外面调用的方法
  3. function login(){
  4. console.log('logining..........');
  5. //调用登录接口
  6. wx.login({
  7. success: function (e) {
  8. console.log('wxlogin successd........');
  9. var code = e.code;
  10. wx.getUserInfo({
  11. success: function (res) {
  12. console.log('wxgetUserInfo successd........');
  13. var encryptedData = encodeURIComponent(res.encryptedData);
  14. thirdLogin(code,encryptedData,res.iv);//调用服务器api
  15. }
  16. })
  17. }
  18. });
  19. }
  20. function thirdLogin(code,encryptedData,iv){
  21. var url = "eeee/xxx/login/ttttt";
  22. var params = new Object();
  23. params.code = code;
  24. params.encryptedData = encryptedData;
  25. params.iv =iv;
  26. buildRequest(new Object(),url,params,{
  27. onPre: function(page){},
  28. onSuccess:function (data){
  29. console.log('my login successd........');
  30. console.log(data);
  31. getApp().globalData.session_id = data.session_id;
  32. getApp().globalData.uid = data.uid;
  33. getApp().globalData.isLogin = true;
  34. },
  35. onError : function(msgCanShow,code,hiddenMsg){
  36. }
  37. }).send();
  38. }
复制代码
复制代码