抖音小程序登录(前端通过tt.login获取code换取openId)
抖音小程序登录
抖音开放平台小程序登录:
https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/basic-ability/microapp-login
前端(通过tt.login获取code)
流程
静默登录依赖小程序 API tt.login,把tt.loginsuccess 回调中返回的 code 传给开发者服务端,换取开发者服务端生成的 token。
具体的前端流程如下:
- 判断抖音宿主是否登录。已登录,下一步。未登录,则显示登录抖音主端的按钮,提示用户登录。
- 登录抖音成功后,tt.login 会返回一个 code,前端携带 code 向开发者服务端请求。
- 开发者服务端通过 code2session 换取 sessionKey、open_id 和 union_id,并生成与 open_id 对应的唯一 token。
- 开发者服务端将 token 返回前端。
- 前端将 token 缓存,下次直接携带 token 向开发者服务端请求数据。
后端
具体流程
从前端的code去调用抖音接口去换取openid等信息,以此生成token
-
先调用接口换取openid
接口为
https://developer.toutiao.com/api/apps/v2/jscode2session
响应为
{
“err_no”: 0,
“err_tips”: “success”,
“log_id”: “2024102117013250E8ABC6F2D070B681DC”,
“data”: {
“session_key”: “hZy6t19VPjFqm********”,
“openid”: “V3WvSshYq9******”,
“anonymous_openid”: “”,
“unionid”: “f7510d9ab***********”
}
} -
我是根据openid和shopId作为用户的唯一依据的,一般来说就是根据openid就可以,如果存在这个用户就查询然后将id放到token的负载之后,没有则先注册到数据库返回id,放入token中
-
返回前端token
String appid = "********;
String secret = "*************************************";
public Map<String, Object> dyMiniLogin(String code, String ipAddr, Long shopsId) {
String url = "https://developer.toutiao.com/api/apps/v2/jscode2session";
// 创建请求体 JSON 对象
com.alibaba.fastjson2.JSONObject requestBody = new com.alibaba.fastjson2.JSONObject();
requestBody.put("anonymous_code", ""); // 如果不需要匿名码,可以留空
requestBody.put("appid", appid);
requestBody.put("code", code);
requestBody.put("secret", secret);
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
// 创建 HttpEntity 对象
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody.toJSONString(), headers);
// 创建 RestTemplate 实例
RestTemplate restTemplate = new RestTemplate();
// 发送 POST 请求并获取响应
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
// 获取响应体
String response = responseEntity.getBody();
// 打印响应日志,便于调试
System.out.println("Response from Douyin: " + response);
// 解析响应
JSONObject resJSON = JSONObject.parseObject(response);
String token = "";
// 检查是否成功
try {
if ("0".equals(resJSON.getString("err_no")) && "success".equals(resJSON.getString("err_tips"))) {
String jsonString = resJSON.toJSONString();// 返回完整的响应 JSON
JSONObject jsonObject = JSON.parseObject(jsonString);
// 获取 data 字段中的内容
JSONObject data = jsonObject.getJSONObject("data");
// 提取 openid
String openId = data.getString("openid");
//根据openId和商铺id查询用户
UserVo userVo = UserVo.builder().openid(openId).shopsId(shopsId).build();
Tiktokuser user = tiktokuserService.selectTiktokuserByOpenIdAndShopsId(userVo);
if (ObjectUtils.isEmpty(user)){
user = new Tiktokuser();
user.setOpenid(openId);
user.setShopsId(shopsId);
//进行注册
tiktokuserService.insertTiktokuser(user);
}
LoginUser loginUser = new LoginUser();
loginUser.setUserid(user.getId());
loginUser.setUsername(openId);
/* HashMap<String, Object> map = new HashMap<>();
map.put("user_id",user.getId());
map.put("openId",openId);*/
// 生成 JWT
TokenService tokenService = new TokenService();
SysUser sysuser = new SysUser();
sysuser.setUserId(user.getId());
sysuser.setUserName(openId);
loginUser.setSysUser(sysuser);
// loginUser.setToken(JwtUtils.createToken(token));
// tokenService.setLoginUser(loginUser);
return tokenService.createToken(loginUser); // 返回完整的响应 JSON
} else {
String errcode = resJSON.getString("err_no");
String errmsg = resJSON.getString("err_tips");
throw new Exception("获取 session_key 失败:状态码:" + errcode + ",信息:" + errmsg);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}