主机参考:VPS测评参考推荐/专注分享VPS服务器优惠信息!若您是商家可以在本站进行投稿,查看详情!此外我们还提供软文收录、PayPal代付、广告赞助等服务,查看详情! |
我们发布的部分优惠活动文章可能存在时效性,购买时建议在本站搜索商家名称可查看相关文章充分了解该商家!若非中文页面可使用Edge浏览器同步翻译!PayPal代付/收录合作 |
小程序是如何实现登录功能的?本文向你介绍了小程序登录的正确打开方式,希望对你有所帮助!
小程序网络组件
https://developers . weixin . QQ . com/mini program/dev/API/network/request/wx . request . html
请求任务描述
RequestTask.abort()方法中断请求任务。request.onheadersreceived(函数回调)侦听HTTP响应头事件。将早于请求完成事件。的请求。offheadersreceived(函数回调)取消对HTTP响应头事件的侦听。request.onchunkreceived(函数回调)侦听transfer -编码块接收事件。收到新块时触发。的请求。offchunkreceived(函数回调)取消对transfer -编码块接收事件的侦听。Wx.request(Object object)属性
这里只列出了常用的属性。请查看所有属性的链接。
类型默认值必需说明urlstring是developer server的接口地址datastring/object/ArrayBuffer没有设置请求头的参数object没有设置请求头,并且不能在头中设置Referer。content -类型默认为application/jsontimeoutnumber无超时时间,单位为毫秒methodstringGET无HTTP请求方法成功function无接口调用成功回调函数failfunction无接口调用失败回调函数completefunction无接口调用结束的回调函数(无论成功还是失败都会执行调用),即使是abort!总结一下:所有的小程序界面基本上都有两个特点:
参数都是一个对象。很容易记忆和展开。
它们都有相同的结果处理方法:它们都有三个回调属性:成功、失败和完成。
在接口执行的各种情况下引入errMsg对象。
属性errMsg对象成功{ errMsg: ;请求:ok ...} fail { errMsg: ;请求:失败..}有些系统在这个fail之后有一个空格,所以要用这个判断,最好用正则表达式。也可以使用indexOf函数,大于-1进行判断。中止{ errMsg: ;请求:失败中止 ...}示例代码
let req task = wx . request({ URL:getApp(). global data . API,success(RES){ if(RES . errmsg = = = = ;请求:ok )console . log( ;res ,RES);},fail(err){//if(err . errmsg . index of( # 39;请求:失败 # 39;) gt-1)console . log( # 39;呃 # 39;,err);if(/^request:fail/i.test(err.errmsg))console . log( ;呃 ,err);},完成(RES){ console . log( ;resOrErr ,RES);}, });const reqTaskOnHeadersReceived =(headers)= gt;{ req task . offheaders received(reqTaskOnHeadersReceived);控制台. log( ;标题 ,标题);//由于请求没有完全完成,我们无法获取请求的状态码,但是可以通过返回的requestBody的长度来判断。//两个注意:1。二~ ~能快速把字符串数字转换成数字。// 2.为什么不到19?是因为后台未经许可返回requestBody时,content -长度为“18”,正常情况下大于19。所以多少要看具体情况。if(~ ~ headers . header[ ;内容-长度 ] lt;19)req task . abort();};req task . onheadersreceived(reqTaskOnHeadersReceived);小程序登录界面
wx.getUserProfile(对象对象)
获取用户信息。该页只能在click事件(例如,在按钮上的bindtap回调中)生成后调用。每个请求都会弹出一个授权窗口,用户同意后会返回userInfo。该界面用于替代wx.getUserInfo,具体参见用户信息界面调整说明。
wx.checkSession(Object对象)
检查登录状态是否已过期。通过wx.login接口获取的用户登录状态具有一定的时效性。用户不使用小程序的时间越长,用户的登录状态就越有可能变得无效。相反,如果用户一直在使用小程序,用户的登录状态仍然有效。具体的时效性逻辑由微信维护,对开发者透明。开发者只需要调用wx.checkSession接口来检查当前用户登录状态是否有效。
登录状态过期后,开发者可以调用wx.login来获取新的用户登录状态。成功的调用表示当前的session_key尚未过期,失败的调用表示session_key已经过期。更多使用方法见小程序登录。
wx.login(Object对象)
调用接口获取登录凭证(代码)。通过凭证可以交换用户的登录状态信息,包括当前小程序的唯一标识符(openid)、用户的唯一标识符(unionid,如果当前小程序绑定了微信开放平台账号)以及本次登录的会话密钥(session_key)。用户数据的加密和解密通信依赖于会话密钥。更多使用方法见小程序登录。
后端登录接口代码的实现
后端NodeJS,web框架KOA 2 . 13 . 4版,路由框架@ KOA/路由器10.1.1版,框架请求2.88.2版,jsonwebtoken用于加密和解密令牌信息,8.5.1版。
//app . jsconst Koa = require( ;koa );const Router = require( ;@ KOA/router ;);const weixin auth = require( ;。/lib/KOA 2-weixin -auth ;);const jsonwebtoken = require( ;jsonwebtoken );const app = new Koa();//applet票证信息const miniProgramAppId = " * * * * * * * * * ;;const miniProgramAppSecret = ;* * * * * * * * * * * ;const weixinAuth = new weixinAuth(miniProgramAppId,miniProgramAppSecret);const JWT _ SECRET = ;JWTSECRET ;//路由中间件需要安装@ KOA/router//Open a route constrator = new router带组({ prefix:"/user ;,});//这是正常的登录方式。//添加一个参数sessionKeyIsValid,表示sessionKey是否仍然是有效的router . post( ;/weixin -登录 ,异步(CTX)= gt;{ let { code,userInfo,encryptedData,iv,session keyi valid } = CTX . request . body;//parse OpenID const token = awaitweixinath . getaccesstoken(code);userinfo . OpenID = token . data . OpenID;//在这里,你可以自己处理,比如在数据库中记录,处理令牌等。let authorization token = jsonwebtoken . sign({ name:userinfo . nickname },jwt _ secret,{ expires in:" 1d ;} );Object.assign(userInfo,{ authorization token });ctx.status = 200ctx.body = { code: 200,msg: ;好的 ,数据:userInfo,};});//lib/KOA 2-weixin -auth . jsconst query string = require( ;querystring );const request = require( ;请求 );const access token = function(data){ if(!(AccessToken的this instanceof返回新的access token(data);} this.data = data};/*!*检查AccessToken是否有效,检查规则是比较当前时间和过期时间* *示例:* ` ``* token . is valid();* ` ``*/access token . prototype . is valid = function(){ return(!!会话密钥 新日期()。getTime() lt;this . data . create _ at+this . data . expires _ in * 1000);};/* * *根据appid和appsecret创建OAuth接口的构造函数*如果需要跨进程跨机器操作,需要全局维护访问令牌*使用令牌的优先级:* * 1。使用当前缓存的令牌对象* 2。调用并开发获取token的传入异步方法,获取token后使用(并缓存)。*示例:* ` ``* var OAuth = require( # 39;oauth # 39);* var API = new OAuth( # 39;appid # 39, '秘密 # 39;);* ````` * @ param { string }在公共平台上申请获得的appid * @ param { string }在公共平台上申请获得的app secret */const auth = function(appid,app secret){ this . appid = appid;this . app secret = app secret;this . store = { };this . gettoken = function(OpenID){ return this . store[OpenID];};this.saveToken = function (openid,token){ this . store[OpenID]= token;};};/* * *获取授权页面的URL地址* @param {String}授权后重定向地址跳转到* @param {String}状态数据由开发者提供* @param {String} scope scope,值为snsapi_userinfo和snsapi_base,前者用于弹出,后者用于跳转*/auth . prototype . getauthorizeurl = function(redirect _ uri,Scope,state){ return new promise((resolve,reject)= >;{ const url = https://open.weixin.qq.com/connect/oauth2/authorize&;;let info = { appid: this.appid,redirect_uri: redirect_uri,scope:scope | | ;snsapi _ base ,state:state | | ;",响应类型: 代码 , };解析(URL+ ;?"+query string . string ify(info)+ ;#微信_重定向 );});};/*!*处理令牌并更新到期时间*/auth . prototype . process token = function(data){ data . create _ at = new date()。gettime();//存储令牌This。SaveToken (data.openid,data);返回AccessToken(数据);};/* * *根据授权获得的代码,换取访问令牌和openid *获得openid后,即可调用微信。获取更多信息的API * @ param { String } code */auth . prototype . getaccesstoken = function(code){ return new promise((resolve,reject))= >;{ const url = https://api.weixin.qq.com/sns/jscode2session&;;//由于这个框架版本很久没有更新了,这里的地址发生了变化,需要修改到上面的地址,否则会出现//41008错误。这也是不直接使用框架,引用局部使用的原因。//const URL = ;https://api.weixin.qq.com/sns/oauth2/access_token&;;const info = { appid: this.appid,secret: this.appsecret,js_code: code,grant _ type: ;授权代码 , };request.post(url,{ form: info },(err,res,body)= gt;{ if(err){ reject(err);} else { const data = JSON.parse(正文);resolve(this . process token(data));} });});};/* * *根据刷新令牌,刷新访问令牌,只有在getAccessToken被调用后才有效* @ param { string } refresh token refresh token */auth . prototype . refresh accesstoken = function(refresh token){ return new promise((resolve,reject)= >;{ const url = https://api.weixin.qq.com/sns/oauth2/refresh_token&;;var info = { appid: this.appid,grant _ type: ;刷新令牌 ,refresh_token: refreshToken,};request.post(url,{ form: info },(err,res,body)= gt;{ if(err){ reject(err);} else { const data = JSON.parse(正文);resolve(this . process token(data));} });});};/* * *根据openid,获取用户信息。*当访问令牌无效时,通过刷新令牌自动获取新的访问令牌。然后获取用户信息* @param {Object|String} options并传入openid或see options */auth . prototype . getuser = async function(OpenID){ const data = this . gettoken(OpenID);控制台. log( ;getUser ,数据);如果(!data){ var Error = new Error( ;没有 的令牌+options . OpenID+ ;,请先授权。");error.name = NoOAuthTokenError ;投掷误差;} const token = AccessToken(数据);var accessTokenif(token . is valid()){ access token = token . data . session _ key;} else { var newToken = await this . refreshaccesstoken(token . data . refresh _ token);access token = new token . data . session _ key;} console . log( ;访问令牌 ,access token);等待这个归来。_getUser(openid,access token);};auth . prototype . _ getUser = function(OpenID,accessToken,lang){ return new Promise((resolve,reject)= gt;{ const url = https://api.weixin.qq.com/sns/userinfo&;;const info = { access _ token:access token,openid: openid,lang:lang | | ;zh _ CN , };request.post(url,{ form: info },(err,res,body)= gt;{ if(err){ reject(err);} else { resolve(JSON . parse(body));} });});};/* * *根据代码,获取用户信息。* @ param { String } code code */auth . prototype . getuserbycode = async function(code){ const token = awaitthis . getaccesstoken(code);return await this . getuser(token . data . OpenID);};module.exports = Auth小程序登录代码的实现
lt!--pages/index.wxml--> ltview class = page -section ; gt lttext class = page -section _ _ title ; gt登录微信
对于一个软件来说,就代码层面而言,要追求最基础的方面(远不止这些,还是先把它们做好吧):
可维护性
所谓“维护”,无非就是修复bug,修复旧代码,添加新代码。所谓“代码易维护”,就是在不破坏原有代码设计或引入新bug的情况下,快速修改或添加代码。所谓“代码不易维护”,就是修改或添加代码要冒很大的引入新bug的风险,而且需要很长时间才能完成。
可读性(可读性)
软件设计大师马丁·福勒(Martin Fowler)曾说过,“任何傻瓜都能写出计算机能理解的代码。优秀的程序员会写出人类能理解的代码。”翻译成中文就是“任何一个傻子都能写出计算机能理解的代码。好的程序员能写出人们能理解的代码。”谷歌甚至有一个叫做可读性的内部认证。只有获得此认证的工程师才有资格在代码评审时批准其他人提交代码。可见代码的可读性有多重要。毕竟代码被读取的次数远远超过它被编写和执行的次数。我们需要看代码是否符合编码标准,命名是否令人满意,注释是否详细,函数长度是否合适,模块划分是否清晰,是否符合高内聚低耦合等等。
扩展性(延展性)
扩展性也是评估代码质量的一个非常重要的标准。代码中预留了一些功能扩展点,可以直接将新的功能代码插入到扩展点中,而不用因为想增加一个功能而大做文章,改动很多原代码。
可重用性(可重用性)
代码的可重用性可以简单理解为尽量减少代码编写的重复,重用现有的代码。
然后让我们优化代码:
模块化
您可以模块化登录代码,如下所示:
//lib/login.js函数loginwithcallback(CB){//建议使用wx.getUserProfile获取用户信息。开发者每次通过这个接口获取用户的个人信息,都需要用户确认。//开发者要保留用户快速填写的头像昵称,避免重复弹窗wx.getUserProfile({ desc:“用于完善会员信息”,//声明获取用户个人信息的目的,稍后会在弹窗中显示。请仔细填写成功:(RES)= gt;{ let { userInfo,encryptedData,iv } = resconst request loginapi =(code)= gt;{//发起网络请求wx . request({ URL:" http://localhost:3000/user/weixin -log in ;,方法: 帖子 ,标题:{ content -type ;: 应用程序/JSON ;,},data: { code,userInfo,encryptedData,iv,},success(RES){ console . log( ;成功请求”,RES . data);let token = RES . data . data . authorization token;wx . setstoragesync( ;令牌 ,token);onUserLogin(令牌);控制台. log( ;授权 ,token);},fail(err){ console . log( ;异常“请求,错误);}, });};const onuserlog in =(token)= gt;{ getApp(). global data . token = token;wx . show toast({ title: ;登录成功“,});如果(cb cb的类型= = 函数 )CB(token);};wx . check session({ success:(RES)= gt;{// session_key尚未过期,并且在此生命周期内一直有效。登录中”);let token = wx . getstoragesync( ;令牌 );if(token)onUserLogin(token);},fail:(RES)= gt;{// session_key已经过期,需要重新执行登录过程wx . log in({ success(res0){ if(res0 . code){ request loginapi(res0 . code));} else { console . log( ;登录失败!"+res0 . errmsg);} }, });}, });}, });}导出默认loginWithCallback承诺
回调问题不利于代码的读取,接下来我们基于Promise对代码进行优化。有了Promise对象,异步操作可以在同步操作的过程中表达,避免嵌套回调函数。此外,Promise对象提供了一个统一的接口,这使得控制异步操作变得更加容易。
几种许诺方式简介
方法名表示Promise.prototype.then方法返回一个新的Promise对象,所以可以写成chain。这种设计使得嵌套的异步操作可以很容易地从"回调函数水平开发"变为"向下"。Promise.prototype.catch是promise.prototype.then (null,rejection)的别名,用于指定出错时的回调函数。Promise对象的错误具有“冒泡”属性,将被传递回来,直到它被捕获。也就是说,错误总是被下一个catch语句捕获。Promise.prototype.finally方法返回一个承诺。在承诺结束时,无论结果是满足还是拒绝,都将执行指定的回调函数。这就为承诺成功完成与否后需要执行的代码提供了一种方式。Promise .这一切避免了同一个语句需要在then()和catch()中写一次的情况。Promise.all方法用于将多个Promise实例包装成一个新的Promise实例。Promise.all方法接受一个数组作为参数,var p = Promise.all([p1,p2,P3]);P1、p2和p3都是Promise对象的实例。(Promise.all方法的参数不一定是数组,但必须有迭代器接口,返回的每个成员都是Promise实例。)P的状态由p1、p2、p3决定,可分为两种情况。(1)只有当p1、p2和p3的状态变为满足时,P的状态才会变为满足。此时p1、p2、p3的返回值组成一个数组,传递给P的回调函数(2)只要p1、p2、p3中有一个被拒绝,P的状态就变成拒绝。此时,第一个被拒绝的实例的返回值将被传递给P的回调函数。Promise.racePromise.race方法还将多个Promise实例包装成一个新的Promise实例。var p = Promise.race([p1,p2,P3]);在上面的代码中,只要p1、p2、p3中有一个实例率先改变状态,P的状态也会随之改变。首先改变的Promise实例的返回值传递给P. Promise.any的返回值接收一个Promise iterable对象,只要其中一个承诺成功,就会返回成功的承诺。所有子例程都处于拒绝状态,总承诺也处于拒绝状态。Promise.allSettled返回所有给定承诺被履行或拒绝后的承诺,带有一个对象数组,每个对象代表相应的承诺结果。相比之下,Promise.all()更适合相互依赖,或者在其中任何一个被拒绝时立即结束。小程序的API接口承诺并模块化了需要登录的调用接口。
1.安装插件。请首先查看npm支持文档。
NP install --保存迷你程序-API -Promise 2。在微信开发者工具右侧的详细信息中勾选npm模块的使用,在菜单栏工具中点击建立npm。
3.初始化代码。
//app . jsimport { promisifyAll } from # 39;迷你程序-API -承诺 # 39;从 ../lib/log in ;;ConstwXp = {} Promisifyall (wx,wXp)//要求令牌的请求统一处理登录和头设置,并处理错误消息wxp。RequestNeedLogin = async function(args){ let token = wx。GetStorageSync(" token ;);如果(!token){ token = await loginwithspromise();}如果(!args . header)args . header = { };args . header[ ;授权 ] = `持票人$ { token } `;返回wxp.request(args)。catch(console . error);};// app.jsApp({ wxp:wxp,});4.重写login.js代码
//lib/log in . jsfunction log in(){ return new Promise((resolve,reject)= gt;{//建议使用wx.getUserProfile获取用户信息。开发者每次通过这个接口获取用户个人信息,都需要用户确认。//开发者要妥善保管用户快速填写的头像昵称,避免重复弹窗wx.getUserProfile({ desc:“用于完善会员信息”,//声明获取用户个人信息的目的,稍后会在弹窗中显示。请认真填写成功:async(res0)= >;{ let { userInfo,encryptedData,iv } = res0const app = getApp();请尝试{ app . wxp . check session();} catch(err){ reject(err);} let token = wx . getstoragesync( ;令牌 );如果(!token){ let res1 = await app . wxp . log in()。catch(err = gt;拒绝(err));设code = res1.codelet RES = await app . wxp . request({ URL: ;http://localhost:3000/user/weixin -log in ;,方法: 帖子 ,标题:{ content -type ;: 应用程序/JSON ;,},数据:{ code,userInfo,encryptedData,iv,} })。catch(err = gt;拒绝(err));token = RES . data . data . authorization token;wx . setstoragesync( ;令牌 ,token);app . global data . token = token;wx . show toast({ title: ;登录成功“,});解决(令牌);} }, });})}导出默认登录;5.呼叫代码
ltview class = 容器第3页+head ; gt lttext class = page -section _ _ title ; gt登录请求调用
这几篇文章你可能也喜欢:
- 如何实现小程序发送服务通知(小程序如何主动向用户发送通知)
- 如何获取小程序的unionid(如何获取小程序的页面路径)
- 生成海报的示例小程序(Java后端)(微信小程序生成海报演示)
- 什么是小程序? 有哪些功能?(什么是小程序?有哪些功能?)
- 介绍如何用小程序生成参数二维码(二维码+小程序参数)
本文由主机参考刊发,转载请注明:如何实现小程序的登录功能(如何实现小程序的登录功能) https://zhujicankao.com/75548.html
评论前必须登录!
注册