springboot 整合 抖音 移动应用 授权

2025-10-11 19:29:42

后端开发,因为没有JavaSDK,maven依赖,用到的是API接口去调用

抖音API开发文档

开发前先申请好移动应用,抖音控制台-移动应用

之后还需要开通所有能开通的能力

拿到应用的 clientKey 和 clientSecret,就可以进入开发了

在your_project/src/main/resources/application.yml中加入 抖音配置

kuaishou:

……

……

douyin:

clientKey: xxxxxxxxxxx

clientSecret: xxxxxxxxxxxxxxxxxxxxxxxx

创建抖音配置类

import lombok.Data;

import org.springframework.boot.context.properties.ConfigurationProperties;

import org.springframework.stereotype.Component;

@Data

@Component

@ConfigurationProperties(prefix = "douyin")

public class DouyinConfig {

/**

* 应用唯一标识,即AppID。

*/

private String clientKey;

/**

* 应用唯一标识对应的密钥

*/

private String clientSecret;

/**

* token/ticket的缓存时间

* 1h50min

*/

private final Long cacheTime=6600L;

/**

* 该接口用于获取接口调用的凭证 client_token。该接口适用于抖音授权;

*/

private final String clientTokenUrl = "https://open.douyin.com/oauth/client_token/";

/**

* 该接口用于 h5 链接拉起抖音发布器分享视频时对开发者身份进行验签

*/

private final String openTicketUrl = "https://open.douyin.com/open/getticket/";

/**

* 获取用户授权第三方接口调用的凭证 access_token

*/

private final String accessTokenUrl = "https://open.douyin.com/oauth/access_token/";

/**

* 追踪分享的视频是否成功

*/

private final String shareUrl = "https://open.douyin.com/share-id/";

/**

* 粉丝关系检测

*/

private final String fansCheck = "https://open.douyin.com/fans/check/";

/**

* 视频详情页跳转链接获取

*/

private final String videoInfo = "https://open.douyin.com/api/douyin/v1/schema/get_item_info/";

创建绑定抖音接口

import lombok.RequiredArgsConstructor;

import org.springframework.validation.annotation.Validated;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**

* 绑定第三方

*/

@Validated

@RequiredArgsConstructor

@RestController

@RequestMapping("/api/bound")

public class BoundThirdPartController extends BaseController {

private final ISysUserService userService;

/**

* 绑定抖音

*/

@PostMapping("/douyin")

public R boundDouyin(@Validated @RequestBody DouyinBound bound) {

return toAjax(userService.boundDouyin(bound, getUserId()));

}

/**

* 绑定快手

* @param bound

* @return

*/

@PostMapping("/kuaishou")

public R boundKuaishou(@Validated @RequestBody KuaishouBound bound){

return toAjax(userService.boundKuaishou(bound, getUserId()));

}

}

import lombok.Data;

import javax.validation.constraints.NotBlank;

@Data

public class DouyinBound {

/**

* 抖音授权码

*/

@NotBlank(message = "抖音授权码不能为空")

private String douyinCode;

}

userService实现

private final IDouyinService douyinService;

@Override

public boolean boundDouyin(DouyinBound bound, Long userId) {

//根据授权码获取抖音授权信息

JSONObject json = douyinService.getDouyinAccessToken(bound.getDouyinCode());

String accessToken = json.get("access_token", String.class);

String openId = json.get("open_id", String.class);

Integer expiresIn = json.get("expires_in", Integer.class);

//查看此openid是否有被绑定过

SysUser old = userMapper.selectOne(Wrappers.lambdaQuery().eq(SysUser::getDouyinOpenId, openId));

if (ObjectUtil.isNotNull(old)) {

if (!old.getUserId().equals(userId)) {

//自己绑定过

//throw new ServiceException("您已绑定该抖音账户,请勿重复绑定!");

//别人绑定过

throw new ServiceException("该抖音已绑定到其他用户!");

}

} else {

//更新用户数据

SysUser user = new SysUser();

user.setUserId(userId);

user.setDouyinOpenId(openId);

return baseMapper.updateById(user) > 0;

}

RedisUtils.setCacheObject(CacheConstants.DOUYIN_ACCESS_TOKEN + userId, accessToken, Duration.ofSeconds(expiresIn));

return true;

}

抖音service 实现

@Slf4j

@RequiredArgsConstructor

@Service

public class DouyinServiceImpl implements IDouyinService {

private final DouyinConfig douyinConfig;

/**

* access_token 为用户授权第三方接口调用的凭证,存储在客户端,可能会被窃取,泄漏后可能会发生用户隐私数据泄漏的风险,建议存储在服务端。

*/

@Override

public JSONObject getDouyinAccessToken(String code) {

//请求参数

Map parma = new HashMap<>();

parma.put("grant_type", "authorization_code");

parma.put("code", code);

parma.put("client_secret", douyinConfig.getClientSecret());

parma.put("client_key", douyinConfig.getClientKey());

//发送请求

JSONObject result = JSONUtil.parseObj(HttpUtil.post(douyinConfig.getAccessTokenUrl(), parma));

//解析结果

if ("success".equals(result.get("message"))) {

JSONObject data = JSONUtil.parseObj(result.get("data"));

if (StringUtils.isEmpty(data.get("access_token", String.class)) ||

StringUtils.isEmpty(data.get("open_id", String.class))) {

throw new ServiceException("授权码错误");

}

return data;

} else {

JSONObject data = JSONUtil.parseObj(result.get("data"));

String errorCode = data.get("error_code", String.class);

if ("10007".equals(errorCode)) {

throw new ServiceException("授权码过期");

} else {

log.error("抖音:error:{}", data.get("description", String.class));

throw new ServiceException("抖音:error:" + data.get("description", String.class));

}

}

}

}

绑定抖音用户已实现,更多java springboot实现抖音功能,请看后续文章