2021-0410 小程序学习记录-登录功能前后端实现

2021-0410 小程序学习记录-登录功能前后端实现及获取用户信息

登录流程

1.小程序利用wx.login()函数获取登录凭证code。code每次调用都不一样,有效期5分钟,在服务器发送给微信接口服务验证一次后失效。
2.小程序将code发给服务器,服务器使用code在微信接口服务校验登录凭证,校验成功返回session_key(会话密钥)和openid,服务器生成token,并将其作为保存session数据的主键(自定义登录态)。随后将token返回给前端。
3.前端收到token并在本地保留,存入缓存。下一次登录时,先将token发送至服务器校验,验证通过则不用再次登录。

前端代码片段:

wx.login({
    //此处做了封装,调用wx.login()函数便会自动接收回调参数res
	success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
         	console.log('login code :' + res.code)
         	//利用post请求发送code至服务器,并接收回调成功参数
            wx.request({
            	url: 'http://127.0.0.1:3000/login',
                method: 'post',
                data: {
                	code: res.code
                },
               	success: res => {
                    console.log('token:' + res.data.token),
                    //将token保存在全局变量中
                    this.globalData.token = res.data.token,
                    //保存在缓存,下一次登录继续使用
                    wx.setStorage({
                    data: res.data.token,
                    key: 'token',
                })
               }
            })
          }
       })
    }

后端代码片段:

var db ={
	session:{},
	user:{}
}
app.post('/login',(req,res)=>{
    //req为前端发过来的请求参数
	console.log('login code:'+req.body.code)
	var url='https://api.weixin.qq.com/sns/jscode2session?appid='+wx.appid+'&secret='+wx.secret+'&js_code='+req.body.code+'&grant_type=authorization_code'
	request(url,(err,response,body)=>{
		console.log('body:'+body)
		var session =JSON.parse(body)
		if(session.openid){
		//定义token(定义登录态)作为查询标志,检验有效期
			var token='token'+new Date().getTime()
		//按照token保存session信息,键值对形式
			db.session[token]=session
			//根据openID保存程序用户的账户信息
			if(!db.user[session.openid]){
				db.user[session.openid]={
					credit:100
				}
			}
		}
		//返回给前端token
		res.json({token:token})
	})
	fs.writeFile('db.txt',db,function(err){
		// console.log('Saved successfully'();
	})	
})
app.get('/checklogin',(req,res)=>{
	var session=db.session[req.query.token]
	console.log('checklogin:'+session)
	res.json({is_login:session!==undefined})
})

获取用户信息

此处只涉及前端
index.js

const app = getApp()

Page({
  data: {
    motto: 'Hello World',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo'),
    canIUseGetUserProfile: true,
    canIUseOpenData: false // 如需尝试获取用户信息可改为false
  },
  // 事件处理函数
  bindViewTap() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onl oad() {
    if(app.globalData.userInfo){
      this.setData({
        userInfo:app.globalData.userInfo,
        hasUserInfo:true
      })
    }
    if (wx.getUserProfile) {
      this.setData({
        canIUseGetUserProfile: true
      })
    }
  },
  getUserProfile(e) {
    // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
    wx.getUserProfile({
      desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        console.log(res)
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    })
  }
})
app.js
```javascript
 onLaunch() {
        // 登录
        this.checkLogin(res=>{
          console.log('is_login:',res.is_login)
          if(!res.is_login){
            this.login()
          }
        })
        //读取用户设置
        wx.getSetting({
          success:res=>{
          //是否同意获取用户信息
            if(res.authSetting['scope.userInfo']){
              wx.getUserProfile({
                success:res=>{
                  console.log(res)
                  this.globalData.userInfo=res.userInfo
                }
              })
            }
          }
        })
      }

index.wxml

<view class="container">
  <view class="userinfo">
    <block wx:if="{{canIUseOpenData}}" class="userinfo-opendata">
      <view class="userinfo-avatar" bindtap="bindViewTap">
        <open-data type="userAvatarUrl"></open-data>
      </view>
      <open-data type="userNickName"></open-data>
    </block>
    <block wx:elif="{{!hasUserInfo}}">
      <button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
      <view wx:else> 请使用1.4.4及以上版本基础库 </view>
    </block>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
      <text class="userinfo-nickname">{{userInfo.city}}</text>
      <text class="userGender" lang='zh CN'></text>
    </block>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
  <button bindtap="credit">获取用户积分</button>
</view>

上一篇:C#9.0新特性


下一篇:笑傲Java面试:面霸修炼手册