小程序登录之支付宝授权的实现示例


Posted in Javascript onDecember 13, 2019

众所周知,微信小程序是可以通过微信本身授权后再登录,平台可以拿到微信用的的账号相关信息,然后保存到数据库中,那么同理在支付宝小程序开发过程中,登录功能的设计也可以如此

小程序登录之支付宝授权的实现示例

上图是官方提供的时序图,具体看一下流程:

在小程序端获取 auth_code,目的是获取用户授权码

把第一步获取的授权码 auth_code 传到咱们自己的后台,也就是说后台需要编写一个接口,方便小程序端的传入

var me = this;
  my.getAuthCode({
   scopes: 'auth_user', // 主动授权(弹框):auth_user,静默授权(不弹框):auth_base
   success: (res) => {
    if (res.authCode) {
     // console.log(app.serverUrl + '/login/' + res.authCode);
     // 调用自己的服务端接口,让服务端进行后端的授权认证
     my.httpRequest({
      url: app.serverUrl + '/login/' + res.authCode,
      method: 'POST',
      header:{
       'content-type': 'application/json'
      },
      dataType: 'json',
      success: (res) => {
       // 授权成功并且服务器端登录成功
       console.log(res);
       me.setData({
        userInfo: res.data.data
       });
      }
     });
    }
   },
  });

后台拿到这个 auth_code 之后,需要调用支付宝的授权平台,从而获取用户的唯一 token 以及 支付宝的userid,都是唯一的,调用的接口为 [alipay.system.oauth.token]

获取到userid后,判断一下这个userid是否在我们自己的数据库中存在,如果存在,直接获取信息,并且直接返回用户对象到前台;如果不存在,则需要从支付宝授权平台再一次去获取支付宝用户的信息。

​调用 [alipay.user.info.share],获取用户信息,这个用户对象里包含了大量的用户真实信息,具体参考如下

@Autowired
  private UserService userService;

  @ApiOperation(value = "统一登录接口", notes = "支付宝小程序唤起登录后调用", httpMethod = "POST")
  @PostMapping("/login/{authCode}")
  public IMoocJSONResult items(
      @ApiParam(name = "authCode", 
      value = "授权码", 
      required = true, 
      example = "授权码") @PathVariable String authCode) throws Exception {

    // 1. 服务端获取access_token、user_id
    AlipaySystemOauthTokenResponse response = getAccessToken(authCode);
    if (response.isSuccess()) {
      System.out.println("获取access_token - 调用成功");
      /**
       * 获取到用户信息后保存到数据
       * 1. 如果数据库不存在对用的 alipayUserId, 则注册
       * 2. 如果存在,则获取数据库中的信息再返回
       */
      String accessToken = response.getAccessToken();
      String alipayUserId = response.getUserId();
      System.out.println("accessToken:" + accessToken);
      System.out.println("alipayUserId:" + alipayUserId);
      
      // 2. 查询该用户是否存在
      Users userInfo = userService.queryUserIsExist(alipayUserId);
      if (userInfo != null) {
        // 如果用户存在,直接返回给前端,表示登录成功
        return IMoocJSONResult.ok(userInfo);
      } else {
        // 如果用户不存在,则通过支付宝api获取用户的信息后,再注册用户到自己平台数据库
        // 获取会员信息
        AlipayUserInfoShareResponse aliUserInfo = getAliUserInfo(accessToken);
        if (aliUserInfo != null) {
           Users newUser = new Users();
           newUser.setAlipayUserId(alipayUserId);
           newUser.setNickname(aliUserInfo.getNickName());
           newUser.setRegistTime(new Date());
           newUser.setIsCertified(aliUserInfo.getIsCertified().equals("T") ? 1 : 0);
           newUser.setFaceImage(aliUserInfo.getAvatar());
           userService.createUser(newUser);
           return IMoocJSONResult.ok(newUser);
        }
      }
    } else {
      System.out.println("获取access_token - 调用失败");
    }
    return IMoocJSONResult.ok();
  }
  
  // 服务端获取access_token、user_id
  private AlipaySystemOauthTokenResponse getAccessToken(String authCode) throws Exception {
    AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", 
        APPID,          // 1. 填入appid
        PRIVATE_KEY,      // 2. 填入私钥 
        "json", 
        "GBK", 
        ALIPAY_PUBLIC_KEY,     // 3. 填入公钥
        "RSA2");
    AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
    request.setGrantType("authorization_code");
    request.setCode(authCode);    // 4. 填入前端传入的授权码authCode
    request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");  // 0. 不用管
    AlipaySystemOauthTokenResponse response = alipayClient.execute(request);

    return response;
  }
    
  // 获取支付宝用户信息
  private AlipayUserInfoShareResponse getAliUserInfo (String accessToken) throws Exception {
    AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
        APPID,          // 1. 填入appid
        PRIVATE_KEY,      // 2. 填入私钥 
        "json", 
        "GBK", 
        ALIPAY_PUBLIC_KEY,     // 3. 填入公钥
        "RSA2");
    AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
    AlipayUserInfoShareResponse response = alipayClient.execute(request, accessToken);
    if(response.isSuccess()){
      System.out.println("获取会员信息 - 调用成功");
      return response;
    }

    return null;
  }

拿到的支付宝用户信息如图:

小程序登录之支付宝授权的实现示例

最终页面的展示效果为:

小程序登录之支付宝授权的实现示例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js常用函数 不错
Sep 08 Javascript
使用js实现雪花飘落效果
Aug 26 Javascript
Javascript随机标签云代码实例
Jun 21 Javascript
jQuery图片切换动画效果
Feb 28 Javascript
关于js对textarea换行符的处理方法浅析
Aug 03 Javascript
详解用Webpack与Babel配置ES6开发环境
Mar 12 Javascript
node.js监听文件变化的实现方法
Apr 17 Javascript
layui table 复选框跳页后再回来保持原来选中的状态示例
Oct 26 Javascript
在vue项目实现一个ctrl+f的搜索功能
Feb 28 Javascript
小程序富文本提取图片可放大缩小
May 26 Javascript
vuex中store存储store.commit和store.dispatch的用法
Jul 24 Javascript
vue穿梭框实现上下移动
Jan 29 Vue.js
小程序使用wxs解决wxml保留2位小数问题
Dec 13 #Javascript
微信小程序点击保存图片到本机功能
Dec 13 #Javascript
微信小程序实现轨迹回放的示例代码
Dec 13 #Javascript
微信小程序 SOTER 生物认证DEMO 指纹识别功能
Dec 13 #Javascript
vue中使用elementUI组件手动上传图片功能
Dec 13 #Javascript
使用uni-app开发微信小程序的实现
Dec 13 #Javascript
webpack DllPlugin xxx is not defined解决办法
Dec 13 #Javascript
You might like
PHP安全配置详细说明
2011/09/26 PHP
Codeigniter实现智能裁剪图片的方法
2014/06/12 PHP
详谈配置phpstorm完美支持Codeigniter(CI)代码自动完成(代码提示)
2017/04/07 PHP
php 猴子摘桃的算法
2017/06/20 PHP
图片上传即时显示缩略图的js代码
2009/05/27 Javascript
用showModalDialog弹出页面后,提交表单总是弹出一个新窗口
2009/07/18 Javascript
下载站控制介绍字数显示的脚本 显示全部 隐藏介绍等功能
2009/09/19 Javascript
location.href 在IE6中不跳转的解决方法与推荐使用代码
2010/07/08 Javascript
javascript简单性能问题及学习笔记
2014/02/04 Javascript
NodeJS学习笔记之Connect中间件应用实例
2015/01/27 NodeJs
vue2.0结合DataTable插件实现表格动态刷新的方法详解
2017/03/17 Javascript
vue-cli的webpack模板项目配置文件分析
2017/04/01 Javascript
js调用刷新界面的几种方式
2017/05/03 Javascript
jQuery结合jQuery.cookie.js插件实现换肤功能示例
2017/10/14 jQuery
node.js基于socket.io快速实现一个实时通讯应用
2019/04/23 Javascript
用vscode开发vue应用的方法步骤
2019/05/06 Javascript
js 实现 list转换成tree的方法示例(数组到树)
2019/08/18 Javascript
小程序实现长按保存图片的方法
2019/12/31 Javascript
JavaScript 空间坐标的使用
2020/08/19 Javascript
浅谈Vue使用Cascader级联选择器数据回显中的坑
2020/10/31 Javascript
详解Numpy中的广播原则/机制
2018/09/20 Python
pandas通过loc生成新的列方法
2018/11/28 Python
Django的models中on_delete参数详解
2019/07/16 Python
python模块hashlib(加密服务)知识点讲解
2019/11/25 Python
详解向scrapy中的spider传递参数的几种方法(2种)
2020/09/28 Python
python 实现性别识别
2020/11/21 Python
荷兰度假屋租赁网站:Aan Zee
2020/02/28 全球购物
应届毕业生求职自荐书
2014/01/03 职场文书
旅游网创业计划书
2014/01/31 职场文书
应用数学专业求职信
2014/03/14 职场文书
销售个人求职信范文
2014/04/28 职场文书
毕业典礼演讲稿
2014/05/13 职场文书
文明工地标语
2014/06/16 职场文书
交通安全责任书范本
2014/07/24 职场文书
php 文件上传至OSS及删除远程阿里云OSS文件
2021/07/04 PHP
Nginx中使用Lua脚本与图片的缩略图处理的实现
2022/03/18 Servers