AuthTwitterRequest.java 6.5 KB
Newer Older
H
Hongwei Peng 已提交
1 2 3
package me.zhyd.oauth.request;

import com.alibaba.fastjson.JSONObject;
4 5 6 7
import com.xkcoding.http.HttpUtil;
import com.xkcoding.http.constants.Constants;
import com.xkcoding.http.support.HttpHeader;
import com.xkcoding.http.util.MapUtil;
H
Hongwei Peng 已提交
8 9 10 11 12
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
13
import me.zhyd.oauth.utils.GlobalAuthUtils;
H
Hongwei Peng 已提交
14 15 16 17 18 19
import me.zhyd.oauth.utils.UrlBuilder;

import java.util.HashMap;
import java.util.Map;

import static me.zhyd.oauth.config.AuthDefaultSource.TWITTER;
20 21
import static me.zhyd.oauth.utils.GlobalAuthUtils.generateTwitterSignature;
import static me.zhyd.oauth.utils.GlobalAuthUtils.urlEncode;
H
Hongwei Peng 已提交
22 23 24 25 26

/**
 * Twitter登录
 *
 * @author hongwei.peng (pengisgood(at)gmail(dot)com)
智布道's avatar
智布道 已提交
27
 * @since 1.13.0
H
Hongwei Peng 已提交
28 29 30
 */
public class AuthTwitterRequest extends AuthDefaultRequest {

H
Hongwei Peng 已提交
31 32
    private static final String PREAMBLE = "OAuth";

H
Hongwei Peng 已提交
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    public AuthTwitterRequest(AuthConfig config) {
        super(config, TWITTER);
    }

    public AuthTwitterRequest(AuthConfig config, AuthStateCache authStateCache) {
        super(config, TWITTER, authStateCache);
    }

    /**
     * Obtaining a request token
     * https://developer.twitter.com/en/docs/twitter-for-websites/log-in-with-twitter/guides/implementing-sign-in-with-twitter
     *
     * @return request token
     */
    public AuthToken getRequestToken() {
        String baseUrl = "https://api.twitter.com/oauth/request_token";

50
        Map<String, String> oauthParams = buildOauthParams();
H
Hongwei Peng 已提交
51 52
        oauthParams.put("oauth_callback", config.getRedirectUri());
        oauthParams.put("oauth_signature", generateTwitterSignature(oauthParams, "POST", baseUrl, config.getClientSecret(), null));
H
Hongwei Peng 已提交
53
        String header = buildHeader(oauthParams);
H
Hongwei Peng 已提交
54

55 56 57 58 59
        HttpHeader httpHeader = new HttpHeader();
        httpHeader.add("Authorization", header);
        String requestToken = HttpUtil.post(baseUrl, null, httpHeader);

        Map<String, String> res = MapUtil.parseStringToMap(requestToken, false);
H
Hongwei Peng 已提交
60 61

        return AuthToken.builder()
62 63 64
            .oauthToken(res.get("oauth_token"))
            .oauthTokenSecret(res.get("oauth_token_secret"))
            .oauthCallbackConfirmed(Boolean.valueOf(res.get("oauth_callback_confirmed")))
H
Hongwei Peng 已提交
65 66 67 68 69 70 71 72 73 74 75
            .build();
    }

    /**
     * Convert request token to access token
     * https://developer.twitter.com/en/docs/twitter-for-websites/log-in-with-twitter/guides/implementing-sign-in-with-twitter
     *
     * @return access token
     */
    @Override
    protected AuthToken getAccessToken(AuthCallback authCallback) {
76
        Map<String, String> oauthParams = buildOauthParams();
H
Hongwei Peng 已提交
77 78
        oauthParams.put("oauth_token", authCallback.getOauthToken());
        oauthParams.put("oauth_verifier", authCallback.getOauthVerifier());
79 80
        oauthParams.put("oauth_signature", generateTwitterSignature(oauthParams, "POST", source.accessToken(), config.getClientSecret(), authCallback
            .getOauthToken()));
H
Hongwei Peng 已提交
81
        String header = buildHeader(oauthParams);
H
Hongwei Peng 已提交
82

83 84 85 86 87 88 89 90 91
        HttpHeader httpHeader = new HttpHeader();
        httpHeader.add("Authorization", header);
        httpHeader.add(Constants.CONTENT_TYPE, "application/x-www-form-urlencoded");

        Map<String, String> form = new HashMap<>(1);
        form.put("oauth_verifier", authCallback.getOauthVerifier());
        String response = HttpUtil.post(source.accessToken(), form, httpHeader, false);

        Map<String, String> requestToken = MapUtil.parseStringToMap(response, false);
H
Hongwei Peng 已提交
92 93

        return AuthToken.builder()
94 95 96 97
            .oauthToken(requestToken.get("oauth_token"))
            .oauthTokenSecret(requestToken.get("oauth_token_secret"))
            .userId(requestToken.get("user_id"))
            .screenName(requestToken.get("screen_name"))
H
Hongwei Peng 已提交
98 99 100 101 102
            .build();
    }

    @Override
    protected AuthUser getUserInfo(AuthToken authToken) {
103
        Map<String, String> queryParams = new HashMap<>();
H
Hongwei Peng 已提交
104 105
        queryParams.put("user_id", authToken.getUserId());
        queryParams.put("screen_name", authToken.getScreenName());
106
        queryParams.put("include_entities", Boolean.toString(true));
H
Hongwei Peng 已提交
107

108
        Map<String, String> oauthParams = buildOauthParams();
H
Hongwei Peng 已提交
109 110
        oauthParams.put("oauth_token", authToken.getOauthToken());

111
        Map<String, String> params = new HashMap<>(oauthParams);
H
Hongwei Peng 已提交
112
        params.putAll(queryParams);
113 114
        oauthParams.put("oauth_signature", generateTwitterSignature(params, "GET", source.userInfo(), config.getClientSecret(), authToken
            .getOauthTokenSecret()));
H
Hongwei Peng 已提交
115
        String header = buildHeader(oauthParams);
116 117 118 119 120

        HttpHeader httpHeader = new HttpHeader();
        httpHeader.add("Authorization", header);
        String response = HttpUtil.get(userInfoUrl(authToken), null, httpHeader, false);
        JSONObject userInfo = JSONObject.parseObject(response);
H
Hongwei Peng 已提交
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143

        return AuthUser.builder()
            .uuid(userInfo.getString("id_str"))
            .username(userInfo.getString("screen_name"))
            .nickname(userInfo.getString("name"))
            .remark(userInfo.getString("description"))
            .avatar(userInfo.getString("profile_image_url_https"))
            .blog(userInfo.getString("url"))
            .location(userInfo.getString("location"))
            .source(source.toString())
            .token(authToken)
            .build();
    }

    @Override
    protected String userInfoUrl(AuthToken authToken) {
        return UrlBuilder.fromBaseUrl(source.userInfo())
            .queryParam("user_id", authToken.getUserId())
            .queryParam("screen_name", authToken.getScreenName())
            .queryParam("include_entities", true)
            .build();
    }

144 145
    private Map<String, String> buildOauthParams() {
        Map<String, String> params = new HashMap<>(5);
H
Hongwei Peng 已提交
146
        params.put("oauth_consumer_key", config.getClientId());
147
        params.put("oauth_nonce", GlobalAuthUtils.generateNonce(32));
H
Hongwei Peng 已提交
148
        params.put("oauth_signature_method", "HMAC-SHA1");
149
        params.put("oauth_timestamp", GlobalAuthUtils.getTimestamp());
H
Hongwei Peng 已提交
150 151 152 153
        params.put("oauth_version", "1.0");
        return params;
    }

154
    private String buildHeader(Map<String, String> oauthParams) {
H
Hongwei Peng 已提交
155 156
        final StringBuilder sb = new StringBuilder(PREAMBLE);

157
        for (Map.Entry<String, String> param : oauthParams.entrySet()) {
H
Hongwei Peng 已提交
158 159 160
            if (sb.length() > PREAMBLE.length()) {
                sb.append(", ");
            }
161
            sb.append(param.getKey()).append("=\"").append(urlEncode(param.getValue())).append('"');
H
Hongwei Peng 已提交
162 163 164 165
        }

        return sb.toString();
    }
H
Hongwei Peng 已提交
166
}