package me.zhyd.oauth.request; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipaySystemOauthTokenRequest; import com.alipay.api.request.AlipayUserInfoShareRequest; import com.alipay.api.response.AlipaySystemOauthTokenResponse; import com.alipay.api.response.AlipayUserInfoShareResponse; import me.zhyd.oauth.cache.AuthStateCache; import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthDefaultSource; import me.zhyd.oauth.enums.AuthResponseStatus; import me.zhyd.oauth.enums.AuthUserGender; import me.zhyd.oauth.exception.AuthException; import me.zhyd.oauth.model.AuthCallback; import me.zhyd.oauth.model.AuthResponse; import me.zhyd.oauth.model.AuthToken; import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.utils.StringUtils; import me.zhyd.oauth.utils.UrlBuilder; /** * 支付宝登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @since 1.0.1 */ public class AuthAlipayRequest extends AuthDefaultRequest { private AlipayClient alipayClient; public AuthAlipayRequest(AuthConfig config) { super(config, AuthDefaultSource.ALIPAY); this.alipayClient = new DefaultAlipayClient(AuthDefaultSource.ALIPAY.accessToken(), config.getClientId(), config.getClientSecret(), "json", "UTF-8", config .getAlipayPublicKey(), "RSA2"); } public AuthAlipayRequest(AuthConfig config, AuthStateCache authStateCache) { super(config, AuthDefaultSource.ALIPAY, authStateCache); this.alipayClient = new DefaultAlipayClient(AuthDefaultSource.ALIPAY.accessToken(), config.getClientId(), config.getClientSecret(), "json", "UTF-8", config .getAlipayPublicKey(), "RSA2"); } @Override protected AuthToken getAccessToken(AuthCallback authCallback) { AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest(); request.setGrantType("authorization_code"); request.setCode(authCallback.getAuth_code()); AlipaySystemOauthTokenResponse response = null; try { response = this.alipayClient.execute(request); } catch (Exception e) { throw new AuthException(e); } if (!response.isSuccess()) { throw new AuthException(response.getSubMsg()); } return AuthToken.builder() .accessToken(response.getAccessToken()) .uid(response.getUserId()) .expireIn(Integer.parseInt(response.getExpiresIn())) .refreshToken(response.getRefreshToken()) .build(); } /** * 刷新access token (续期) * * @param authToken 登录成功后返回的Token信息 * @return AuthResponse */ @Override public AuthResponse refresh(AuthToken authToken) { AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest(); request.setGrantType("refresh_token"); request.setRefreshToken(authToken.getRefreshToken()); AlipaySystemOauthTokenResponse response = null; try { response = this.alipayClient.execute(request); } catch (Exception e) { throw new AuthException(e); } if (!response.isSuccess()) { throw new AuthException(response.getSubMsg()); } return AuthResponse.builder() .code(AuthResponseStatus.SUCCESS.getCode()) .data(AuthToken.builder() .accessToken(response.getAccessToken()) .uid(response.getUserId()) .expireIn(Integer.parseInt(response.getExpiresIn())) .refreshToken(response.getRefreshToken()) .build()) .build(); } @Override protected AuthUser getUserInfo(AuthToken authToken) { String accessToken = authToken.getAccessToken(); AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest(); AlipayUserInfoShareResponse response = null; try { response = this.alipayClient.execute(request, accessToken); } catch (AlipayApiException e) { throw new AuthException(e.getErrMsg(), e); } if (!response.isSuccess()) { throw new AuthException(response.getSubMsg()); } String province = response.getProvince(), city = response.getCity(); String location = String.format("%s %s", StringUtils.isEmpty(province) ? "" : province, StringUtils.isEmpty(city) ? "" : city); return AuthUser.builder() .rawUserInfo(JSONObject.parseObject(JSONObject.toJSONString(response))) .uuid(response.getUserId()) .username(StringUtils.isEmpty(response.getUserName()) ? response.getNickName() : response.getUserName()) .nickname(response.getNickName()) .avatar(response.getAvatar()) .location(location) .gender(AuthUserGender.getRealGender(response.getGender())) .token(authToken) .source(source.toString()) .build(); } /** * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 * @since 1.9.3 */ @Override public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("app_id", config.getClientId()) .queryParam("scope", "auth_user") .queryParam("redirect_uri", config.getRedirectUri()) .queryParam("state", getRealState(state)) .build(); } }