当前位置: 首页 > news >正文

智能提醒助理系列-小程序静默登录

        本系列文章记录“智能提醒助理”wx公众号 建设历程。

本文介绍,如何让用户进入小程序之后就锁定用户,开始使用功能,去掉繁琐的登录认证流程。

一、需求出发点

用户进入小程序之后就开始使用功能,去掉繁琐的登录流程。拿来即用。

二、实现路径分析

方案一、小程序初始化之后,获取code,在服务端通过code获取openid作为用户标识。

方案二、在用户触发请求时,进行拦截,判断是否没有登录,则获取code,在服务端通过code获取openid作为用户标识。

三、最终方案

选择 方案二

四、实施路径

1、请求拦截设计

// 引入 uni-ajax 模块
import ajax from '@/uni_modules/u-ajax'
import {getAccessToken, xcxlogin} from '@/common/auth'
import {toast} from '@/common/common'
import config from '@/config'
import store from '@/store/index'const baseUrl = config.baseUrl + config.baseApi;
const appId = config.appId;// 创建请求实例
const instance = ajax.create({// 初始配置baseURL: baseUrl,// needAuth: true
})// 添加请求拦截器
instance.interceptors.request.use(async config => {let token = getAccessToken();console.log("请求拦截器 config:",token, config.url)console.log("请求拦截器 member:",store.state.member.id)if (token ==="" && config.url !=="/auth/loginByXcx" ) {if(uni.getStorageSync("xcxlogin")==="1"){console.log("重复请求")return config;}uni.setStorageSync("xcxlogin","1")await xcxlogin();//登录uni.setStorageSync("xcxlogin","0")token = getAccessToken();}config.header['token'] = token;config.header['appId'] = appId;return config;
})// 添加响应拦截器
instance.interceptors.response.use(response => {console.log("响应拦截器:response.data.msg==>",response)console.log("响应拦截器:response.data.msg==>",response.data.msg)let statusCode = response.statusCode;if (statusCode === 200) {let code = response.data.code || 0;switch (code) {case '400':uni.showToast({title: response.data.msg, icon: 'none', duration: 2000})break;case '401':// token 自动续期xcxlogin();//toast(response.data.msg)break;case '500':uni.showToast({title: response.data.msg, icon: 'none', duration: 2000})break;}} else {toast("请求失败")}// 对响应数据做些什么return response.data},error => {// 对响应错误做些什么return Promise.reject(error)}
)// 导出 create 创建后的实例
export default instance

2、用户登录设计

import store from '@/store/index'
import request from '@/api/config/request';const AccessTokenKey = 'ACCESS_TOKEN'
const RefreshTokenKey = 'REFRESH_TOKEN'// ========== Token 相关 ==========export function getAccessToken() {return uni.getStorageSync(AccessTokenKey)
}export function getRefreshToken() {return uni.getStorageSync(RefreshTokenKey)
}export function setToken(token) {uni.setStorageSync(AccessTokenKey, token)uni.setStorageSync(RefreshTokenKey, token)
}export function removeToken() {uni.removeStorageSync(AccessTokenKey)uni.removeStorageSync(RefreshTokenKey)
}export async function loginByXcx(code) {let res = await request.post({url: '/auth/loginByXcx',data: {'code': code}});const loginRes = res.data;setToken(loginRes["token"]);// 设置用户信息store.commit('SET_MEMBER', loginRes["userInfo"]);return res;
}// 用户静默登录
export async function xcxlogin() {let res = await uni.login({provider: 'weixin', // 使用微信登录});return await loginByXcx(res[1]["code"])
}

3、服务端静默登录设计

/** 微信小程序登录 */@RequestMapping("loginByXcx")public Object loginByXcx(@RequestBody String data) throws IOException {StopWatch stopWatch = new StopWatch();stopWatch.start("获取 登陆凭证");// 获取 登陆凭证codelog.info("loginByXcx,code:{}",data);String loginIp = IpUtils.getIpAddr(request);// ip黑名单 校验
//    String login_black_ip_list = paramDictService.getKey(CacheConstant.XCX_LOGIN_BLACK_IP_LIST);//    if (loginIp.matches(login_black_ip_list)) {
//      return R.failure("登录失败,疑似机器人注册!");
//    }// 获取 登陆凭证codeHashMap<String, Object> jsonParam = JsonUtil.toObj(data, HashMap.class);String code = "";if (!StringUtils.isEmpty(jsonParam.get("code"))) {code = (String) jsonParam.get("code");}if(StringUtils.isEmpty(code)){return R.failure("登录失败,code缺失");}stopWatch.stop();stopWatch.start("jscode2session 获取openid unionid");// jscode2session 获取openid unionidString resData = null;try {resData = wechatUtil.code2session(code);} catch (Exception e) {return R.failure("登录失败,获取openid失败");}stopWatch.stop();stopWatch.start("jscode2session 解析响应结果");HashMap<String, String> sessionData = JsonUtil.toObj(resData, HashMap.class);log.info("loginByXcx,sessionData:{}",sessionData);String xcxOpenId = sessionData.get("openid");String unionid = sessionData.get("unionid");// 解析响应结果if (StringUtils.isEmpty(xcxOpenId)) {return R.failure("登录失败");}stopWatch.stop();stopWatch.start("静默注册");// 静默注册UserInfo userInfo = userInfoService.silenceRegister(unionid,loginIp,xcxOpenId,"");log.info("loginByXcx,静默注册完成:{}",userInfo.getId());stopWatch.stop();stopWatch.start("创建token");// 创建tokenMap<String, Object> tokenMap = tokenService.createToken(userInfo.getId(), userInfo.getNickName());String token = MapUtils.getString(tokenMap, "token");log.info("创建token:" + token);stopWatch.stop();stopWatch.start("获取整合后的用户信息");// 获取整合后的用户信息UserInfoVo resUserInfo = userInfoService.getUserInfo(userInfo.getId());stopWatch.stop();log.info("stopWatch 总耗时:{}",stopWatch.getTotalTimeMillis());log.info("stopWatch 详细信息:{}",stopWatch.prettyPrint());HashMap resultObj = new HashMap();resultObj.put("token", token);resultObj.put("userInfo", resUserInfo);return R.success(resultObj);}

五、总结

静默登录的好处在于,使用既注册,减少用户操作、降低犹豫期,先识别用户,后续再引导用户完善资料,最小化设计。比如:设置头像、昵称等用户信息。

从使用上来讲,只要有用户标识,就可以使用功能做交易了,如果用户需要展示个性化信息,可以再设置。

后续 在设计分享推荐功能的时候,就可以让用户分享即可关联推荐人。

欢迎大家来体验这款新上线的 智能提醒工具,感兴趣的在公众号 留言交流哈。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 纯CSS实现卡片欢动效果
  • vite 打包 学习
  • 自然语言处理-词向量转换
  • 数据结构:树与二叉树
  • Pygame中获取鼠标按键状态的方法
  • 【高级编程】实用类详解(补充)StringBuffer类 和 StringBuilder类
  • UE5 C++ 读取图片插件(一)
  • 【刷题笔记】删除并获取最大点数粉刷房子
  • 2024国赛数学建模A题思路模型代码
  • 计算机网络 第1章 概述
  • C++的四种规范的类型转换
  • 坐牢第三十四天(c++)
  • shell判断、if语句
  • 探索C++编程技巧:计算两个字符串的最长公共子串
  • 内网Exadata使用git的配置过程
  • python3.6+scrapy+mysql 爬虫实战
  • [译] 怎样写一个基础的编译器
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Angular 响应式表单 基础例子
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • Django 博客开发教程 8 - 博客文章详情页
  • EOS是什么
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • JAVA多线程机制解析-volatilesynchronized
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • jdbc就是这么简单
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • log4j2输出到kafka
  • Lucene解析 - 基本概念
  • Vue全家桶实现一个Web App
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 让你的分享飞起来——极光推出社会化分享组件
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 移动端解决方案学习记录
  • 中文输入法与React文本输入框的问题与解决方案
  • gunicorn工作原理
  • 如何正确理解,内页权重高于首页?
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • (03)光刻——半导体电路的绘制
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (未解决)macOS matplotlib 中文是方框
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (一)Dubbo快速入门、介绍、使用
  • (转)iOS字体
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • .Net IE10 _doPostBack 未定义
  • .NET 动态调用WebService + WSE + UsernameToken
  • .Net 基于MiniExcel的导入功能接口示例
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?