微信小程序授权登录流程

微信小程序授权登录流程https developers weixin com miniprogram dev framework open ability login html nbsp nbsp nbsp 微信小程序官方 API 说明 调用 nbsp wx login nbsp 获取 nbsp 临时登录凭证 code nbsp 并回传到开发者服务器 调用 nbsp code2Session nbsp 接口 换取 nbsp 用户唯一标识 OpenID nbsp 和 nbsp 会话密钥 session k

https://developers.weixin..com/miniprogram/dev/framework/open-ability/login.html     微信小程序官方API

微信小程序授权登录流程

说明:

  1. 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  2. 调用 code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key

之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

注意:

  1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥
  2. 临时登录凭证 code 只能使用一次

 

这里仅按照官方推荐的规范来

0. 前置条件

1.检测登录是否有效,如果无效则清楚登录信息(wx.checkSession);

3. 客户端获得code,并将code传给第三方服务端

微信小程序端调用wx.login,获取登录凭证(code),并调用接口,将code发送到第三方客户端

4. 第三方服务端用code换session_key和openid

小程序端将code传给第三方服务器端,第三方服务器端调用接口,用code换取session_key和openid

5. 第三方服务端生成新的session(3rd_session)

第三方服务器端拿到请求回来的session_key和openid,先留着,不能给客户端;然后用操作系统提供的真正随机数算法生成一个新的session,叫3rd_session

6. 第三方服务端建立对应关系,并存储

将3rd_session作为key,微信服务端返回的session_key和openid作为值,保存起来

7. 第三方服务端将3rd_session发送到客户端

客户端只拿到3rd_session就够了,大人说话小孩别插嘴,小程序不需要知道session_key和openid

8. 正常请求

小程序每次请求都将3rd_session放在请求头里,第三方服务端解析判断合法性,并进行正常的逻辑处理。

 

下面就封装一个小程序授权登录的组件

目录结构

微信小程序授权登录流程

1.server.js

 //检测登录是否有效,如果无效则清除登录信息 module.exports = { checkLogs() {     let utoken = wx.getStorageSync("userInfo").utoken;     if (typeof utoken == "undefined") {       return false;     }     this.sendRequest({       url: '',   //  //检测登录是否有效的接口       data: {         utoken       },       method: 'POST',       success: res => {         if (res.data.code != 200) {           wx.removeStorageSync('userInfo');         }       },       fail: () => {         wx.removeStorageSync('userInfo');       }     })   },  //这里使用了iview框架,全局控制handleShow方法,授权登录的显示 login: function() {     const selector = '#login'     const pages = getCurrentPages();     const ctx = pages[pages.length - 1];     const componentCtx = ctx.selectComponent(selector);     if (!componentCtx) {       console.error('无法找到对应的组件,请按文档说明使用组件');       return null;     }     componentCtx.handleShow();   } }

app.js

var server = require('./utils/server'); App({   onLaunch: function() {     server.checkLogs();//全局调用checkLogs(),检查登录是否失效   },   globalData: {} })

login.wxml

 
   
  
      
   
     
  注意:wx.authorize({scope: "scope.userInfo"}),无法弹出授权窗口,请使用

login.js

// component/login/login.js const server = require('../../utils/server.js'); Component({   properties: {   },   data: {     formid: null,     visible: false   },   methods: {     handleShow() {       this.setData({         visible: true       })     },     handleHide() {       this.setData({         visible: false       })     },     touchMove() {       return false;     },     cantchTap() {       return false;     },     getUserInfo(res) {       if (res.detail.errMsg == 'getUserInfo:ok') {         let userInfo = {           ...res.detail.userInfo         }         wx.login({           success: e => {                    let code = e.code;  //调用wx.login,获取登录凭证(code),并调用接口,将code发送到第三方客户端             server.sendRequest({               url: '',       //小程序端将code传给第三方服务器端,第三方服务器端调用接口,用code换取session_key和openid               data: {                 encryptedData: res.detail.encryptedData,                 iv: res.detail.iv,                 code: code               },               method: 'POST',               success: res => {                 if (res.data.code == 200) {                   userInfo = {                     ...userInfo,                     ...res.data.result                   }                   console.log(userInfo);                   console.log(res.data.result)                   wx.setStorageSync('userInfo', userInfo);                   //授权成功                   this.triggerEvent('login', {                     status: 1                   })                   this.$Message({                     content: '登录成功',                     type: "success"                   })                   this.handleHide();                 } else {                   this.triggerEvent('login', {                     status: 0                   })                   this.$Message({                     content: '登录失败',                     type: 'error'                   });                   this.handleHide();                 }               }             })           }         })       } else {         this.triggerEvent('login', {           status: 0         })         this.$Message({           content: '登录失败',           type: 'error'         });         this.handleHide();       }     },     $Message(options) {  //把iview框架里的方法抽取出来       const componentCtx = this.selectComponent("#message");       componentCtx.handleShow(options);     }   } })

login.json

​ {   "component": true,   "usingComponents": {     "i-message": "/component/iview/message/index"  //引用iview框架里全局提示框   } } ​

login.wxss

index.wxml

 
  
      
   
         
         
     
       { 
      {userInfo.nickName}} 
         
      
   
         
    微信小程序授权登录流程     
     
       未登录 
         
    
   
  
      
   
         
    
      我的订单 
         
    
            
     
       查看更多 
            
     微信小程序授权登录流程      
       
    
   
  

index.js

const server = require('../../utils/server.js'); Page({   data: {     useInfo: null   },   onLoad: function(options) {},   onShow: function() {   },   onLogin(res) {  // 授权成功的回调,根据子组件传过来的status     if (res.detail.status == 1) {       let userInfo = wx.getStorageSync('userInfo');       this.setData({         userInfo       })     }   },   navigateTo(option) {  // 封装一个具有判断是否授权登录的跳转方法     if (wx.getStorageSync("userInfo")) {       wx.navigateTo(option);     } else {       server.login();     }   },   seeMore() {     this.navigateTo({       url: '/pages/order/orderList/orderList'     })   }, })

index.wxss

page {   background-color: #eee; } .head {   width: 100%;   height: 250rpx;   background-color: #fff;   box-sizing: border-box;   padding: 0 20rpx;   border-top: 1rpx solid #eee;   display: flex;   align-items: center;   justify-content: flex-start; } .avatarImg {   width: 150rpx;   height: 150rpx;   border-radius: 50%; } .nickname {   display: inline-block;   font-size: 40rpx;   font-weight: 600;   color: #;   margin-left: 20rpx; } .order, .tool {   margin-top: 20rpx;   background-color: #fff; } .list {   border-bottom: 2rpx solid #eee;   height: 100rpx;   box-sizing: border-box;   padding: 0 20rpx; } .orderTitle {   display: flex;   align-items: center;   justify-content: space-between; } .listTitle {   color: #;   font-size: 35rpx; } .readMore {   line-height: 100rpx;   font-size: 30rpx;   color: #;   display: flex;   align-items: center; } .toRight {   width: 28rpx;   height: 28rpx;   margin-left: 20rpx; }

index.json

{     "usingComponents": {         "login": "/component/login/login",         "i-message": "/component/iview/message/index"     } }

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/208411.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 上午11:39
下一篇 2026年3月19日 上午11:40


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号