uniLogin 一键登录

一、通过传统服务器连接uniCloud云函数

首先上传云函数:官网地址

// 云函数验证签名,此示例中以接受GET请求为例作演示
const crypto = require( 'crypto' )
exports.main = async(event) => {
 
  const secret =  'your-secret-string' // 自己的密钥不要直接使用示例值,且注意不要泄露
  const hmac = crypto.createHmac( 'sha256' , secret);
 
  let params = event.queryStringParameters
  const sign = params.sign
  delete params.sign
  const signStr = Object.keys(params).sort().map(key => {
    return `${key}=${params[key]}`
  }).join( '&' )
 
  hmac.update(signStr);
 
  if (sign!==hmac.digest( 'hex' )){
    throw new Error( '非法访问' )
  }
 
  const {
    access_token,
    openid
  } = params
  const res = await uniCloud.getPhoneNumber({
    provider:  'univerify' ,
    appid:  'xxx' ,  // DCloud appid,不同于callFunction方式调用,使用云函数Url化需要传递DCloud appid参数
    apiKey:  'xxx' ,  // 在uniCloud控制台开通一键登录服务并获取apiKey
    apiSecret:  'xxx' ,  // 在uniCloud控制台开通一键登录服务并获取apiSecret
    access_token: access_token,
    openid: openid
  })
  // 返回手机号给自己服务器
  return res
}

  返回结果:

{
	"data": {
		"code": 0,
		"success": true,
		"phoneNumber": "166xxxx6666"
	},
	"statusCode": 200,
	"header": {
		"Content-Type": "application/json; charset=utf-8",
		"Connection": "keep-alive",
		"Content-Length": "53",
		"Date": "Fri, 06 Nov 2020 08:57:21 GMT",
		"X-CloudBase-Request-Id": "xxxxxxxxxxx",
		"ETag": "xxxxxx"
	},
	"errMsg": "request:ok"
}

 

java后端工作:

public AuthFrontLoginRespVO uniLogin(AuthUniLoginReqVO reqVO) {

    log.info("uniLogin获取的mobile的accessToken为:{}======openid为:{}" + reqVO.getAccessToken(),reqVO.getOpenid());
    JSONObject result = getUniMobileInfo(reqVO.getAccessToken(), reqVO.getOpenid());
    //失败案例{"success":false,"error":{"code":"FunctionBizError","message":"5000:errCode: 5000 | errMsg: 获取手机号码失败:获取号码失败"}}
    //登录成功{"code":0,"success":true,"phoneNumber":"18888888888"}

    //判断是否正常相应
    if(!result.containsKey("success")){
        log.info(result.toJSONString());
        throw new ServiceException(UNI_GET_MOBILE_FAIL);
    }
    if(!result.getBoolean("success") ){
        log.info(result.toJSONString());
        throw new ServiceException(UNI_GET_MOBILE_FAIL);
    }
    //获取mobile
    String mobile = result.getString("phoneNumber");
    if(!ValidationUtils.isMobile(mobile)){
        log.info(result.toJSONString());
        throw new ServiceException(UNI_GET_MOBILE_FAIL);
    }

    reqVO.setMobile(mobile);
    // 使用uni获取的手机号登录
    OnlineUsersDO user = uniVerify(reqVO);
    // 创建 Token 令牌,记录登录日志
    AuthFrontLoginRespVO respVO=createTokenAfterLoginSuccess(user.getId(),user.getUserName(), LoginLogTypeEnum.LOGIN_UNI);
    respVO.setUserInfo(OnlineUsersConvert.INSTANCE.convertVO(user));
    return respVO;
}
private JSONObject getUniMobileInfo(String accessToken,String openid) {
    JSONObject result = new JSONObject();

    //调用uniapp云函数、置换出、用户手机号码出来。
    String sign = HeaUtil.sha256_HMAC("access_token="+accessToken+"&openid="+openid, this.uniLoginSecret);
    String urlString = this.uniLoginUrl +"?access_token="+accessToken+"&openid="+openid+"&sign="+sign;

    //失败案例{"success":false,"error":{"code":"FunctionBizError","message":"5000:errCode: 5000 | errMsg: 获取手机号码失败:获取号码失败"}}
    //登录成功{"code":0,"success":true,"phoneNumber":"18888888888"}

    try{
        String resultStr = HttpUtil.get(urlString);
        result = JSONObject.parseObject(resultStr);
    }catch (Exception e){
        e.printStackTrace();
        log.error("从uniCloud云函数获取手机号失败");
    }

    return result;
}

 

 

 

package cn.iocoder.yudao.module.system.util;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

/**
 * @Describe: Hmac加密工具类
 */
public class HeaUtil  {


    /**
     * sha256_HMAC加密
     * @param message 消息
     * @param secret 秘钥
     * @return 加密后字符串
     */
    public static String sha256_HMAC(String message, String secret) {
        String hash = "";
        try {
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
            hash = byteArrayToHexString(bytes);
        } catch (Exception e) {
            System.out.println("Error HmacSHA256 ===========" + e.getMessage());
        }
        return hash;
    }

    /**
     * 将加密后的字节数组转换成字符串
     *
     * @param b
     *字节数组
     * @return 字符串
     */
    private static String byteArrayToHexString(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b != null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1)
                hs.append('0');
            hs.append(stmp);
        }
        return hs.toString().toLowerCase();
    }
}
posted @ 2023-10-18 11:49  风中追风boy  阅读(675)  评论(0编辑  收藏  举报