Java实现Twiiter授权
Joel
发布于 2023-02-16 / 1178 阅读 / 0 评论 / 31 点赞

Java实现Twiiter授权

前言

Twitter提供了丰富的API接口,这些API接口基本上可以满足在Twitter应用上的操作(发送、转发、引用、评论、查找Twitter、关注、拉黑用户)。本文教程纯后端java实现Twitter API的操作。

准备工作

  1. 申请Twitter开发者账号
    申请地址:https://developer.twitter.com/
    Snipaste_2023-05-16_17-22-00
    Snipaste_2023-05-16_17-30-26
    申请理由可以随便写,现在申请没有以前那么严格不需要审核了,但是从今年4月份开始申请的开发者账号对API接口进行了限制,目前免费账号只可以访问下面这些API。
    Snipaste_2023-05-16_18-02-56
    Snipaste_2023-05-16_18-04-48

授权流程图

Snipaste_2023-05-18_23-14-07

流程描述:先构建授权链接(请求授权Twitter的权限范围)->用户点击授权链接同意授权->Twitter服务器请求我们提供的回调地址->回调接口处理回调请求保存用户的相关信息->授权成功

设置ClientID和ClientSecret

Snipaste_2023-05-17_13-44-12
Snipaste_2023-05-17_13-50-58

设置回调接口

Snipaste_2023-05-17_13-52-58-1684423572951
Snipaste_2023-05-17_13-53-40

package com.joel.twittertojava.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.joel.twittertojava.service.TwitterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Joel
 * @since 2023/5/16
 **/
@Service
@Slf4j
public class TwitterServiceImpl implements TwitterService {

    static final String clientId = "";
    static final String clientSecret = "";
    static final String callBackUrl = "http://127.0.0.1:8080/twitter/callback";
    static final String codeChallenge = Base64.getUrlEncoder().encodeToString(RandomUtil.randomString(48).getBytes(StandardCharsets.UTF_8));

    @Override
    public String oauth2Url() {
        String state = IdUtil.simpleUUID();//这里可以用业务的唯一ID
        return "https://twitter.com/i/oauth2/authorize?response_type=code&scope=tweet.read%20users.read%20follows.read%20" +
                "like.read%20offline.access&client_id=" + clientId + "&redirect_uri=" + callBackUrl + "&state=" + state + "&code_challenge=" + codeChallenge + "&code_challenge_method=plain";
    }

    @Override
    public void oauth2CallBack(HttpServletRequest request) {
        String code = request.getParameter("code");
        String state = request.getParameter("state");
        String url = "https://api.twitter.com/2/oauth2/token";
        String clientCredentials = clientId + ":" + clientSecret;
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("grant_type", "authorization_code");
        paramMap.put("code", code);
        paramMap.put("state", state);
        paramMap.put("code_verifier", codeChallenge);
        paramMap.put("redirect_uri", callBackUrl);
        HttpResponse response = HttpRequest.post(url).form(paramMap)
                .auth("Basic " + Base64.getUrlEncoder().encodeToString(clientCredentials.getBytes(StandardCharsets.UTF_8)))
                .execute();
        if (response.getStatus() == HttpStatus.HTTP_OK) {
            JSONObject body = JSONObject.parseObject(response.body());
            String tokenType = body.getString("token_type");
            String accessToken = body.getString("access_token");
            String refreshToken = body.getString("refresh_token");
            //通过accessToken获取用户信息
            HttpResponse rep = HttpRequest.get("https://api.twitter.com/2/users/me").bearerAuth(accessToken).execute();
            if (rep.getStatus() == HttpStatus.HTTP_OK) {
                JSONObject userBody = JSONObject.parseObject(rep.body());
                JSONObject userData = userBody.getJSONObject("data");
                if (userData != null) {
                    String id = userData.getString("id");
                    String name = userData.getString("name");
                    String username = userData.getString("username");
                    System.out.println("id:" + id);
                    System.out.println("name:" + name);
                    System.out.println("username:" + username);
                }
            } else {
                log.error(rep.body());
            }

        } else {
            log.error(response.body());
        }
    }

}

构建好授权链接点开跳去授权
Snipaste_2023-05-18_18-20-30

通过回调接口可以获取到用户的access_token,此后就可以用这个授权凭证去调用其他API实现功能。
例子:授权发推特

@Override
    public void sendTweet(String content, String bearerToken) {
        String url = "https://api.twitter.com/2/tweets";
        HashMap<String, Object> param = new HashMap<>(1);
        param.put("text", content);
        HttpResponse execute = HttpRequest.post(url).bearerAuth(bearerToken).body(JSON.toJSONString(param)).execute();
        if (execute.getStatus() != HttpStatus.HTTP_CREATED) {
            log.error(execute.body());
        }
    }

代码地址

https://github.com/joelwu08/Twitter_to_java


评论