1
0
mirror of synced 2025-12-12 01:08:06 +08:00

Compare commits

...

10 Commits

Author SHA1 Message Date
yadong.zhang
af8fda700b 📝 更新文档 2021-07-28 13:36:36 +08:00
yadong.zhang
881a87ed95 📝 修复 twitter 平台无法获取用户邮箱的问题 2021-07-28 09:53:44 +08:00
yadong.zhang
4c8fdbae49 📝 修复“淘宝”平台授权登录后没有uid的问题、增加刷新token的功能 2021-07-06 22:19:30 +08:00
yadong.zhang
e8db2dd282 📝 更新文档 2021-06-03 20:53:16 +08:00
yadong.zhang
90374762e4 增加“程序员客栈” 2021-06-03 15:18:51 +08:00
yadong.zhang
e5d44e91b8 👽 优化代码 2021-05-14 17:02:12 +08:00
yadong.zhang
41559fc954 📝 更新文档 2021-05-11 12:28:38 +08:00
yadong.zhang
d354278e7d 📝 更新文档 2021-05-11 12:27:15 +08:00
yadong.zhang
c2d6661a76 !24 update README.md. maxkey update
Merge pull request !24 from MaxKeyTop/N/A
2021-05-11 12:22:30 +08:00
MaxKeyTop
5ee87760be update README.md. maxkey update 2021-05-10 21:03:41 +08:00
11 changed files with 224 additions and 34 deletions

View File

@@ -1,3 +1,15 @@
## 1.16.2
### 2021/7/28
- 发布 v1.16.2
- 新增
- 集成“程序员客栈”平台登录
- 修改
- 更新文档
- 修复“淘宝”平台授权登录后没有`uid`的问题、增加刷新token的功能
- 修复“Twitter”平台授权登录后获取不到用户邮箱的问题
## 1.16.1
### 2021/4/19

View File

@@ -6,7 +6,7 @@
</p>
<p align="center">
<a target="_blank" href="https://search.maven.org/search?q=JustAuth">
<img src="https://img.shields.io/badge/Maven%20Central-1.16.1-blue" ></img>
<img src="https://img.shields.io/github/v/release/justauth/JustAuth?style=flat-square" ></img>
</a>
<a target="_blank" href="https://gitee.com/yadong.zhang/JustAuth/blob/master/LICENSE">
<img src="https://img.shields.io/apm/l/vim-mode.svg?color=yellow" ></img>
@@ -14,9 +14,6 @@
<a target="_blank" href="https://www.oracle.com/technetwork/java/javase/downloads/index.html">
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" ></img>
</a>
<a target="_blank" href="https://apidoc.gitee.com/yadong.zhang/JustAuth/" title="API文档">
<img src="https://img.shields.io/badge/Api%20Docs-1.16.1-orange" ></img>
</a>
<a target="_blank" href="https://justauth.wiki" title="参考文档">
<img src="https://img.shields.io/badge/Docs-latest-blueviolet.svg" ></img>
</a>
@@ -59,7 +56,7 @@ These artifacts are available from Maven Central:
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.16.1</version>
<version>1.16.2</version>
</dependency>
```
- Using JustAuth

View File

@@ -6,7 +6,7 @@
</p>
<p align="center">
<a target="_blank" href="https://search.maven.org/search?q=JustAuth">
<img src="https://img.shields.io/badge/Maven%20Central-1.16.1-blue" ></img>
<img src="https://img.shields.io/github/v/release/justauth/JustAuth?style=flat-square" ></img>
</a>
<a target="_blank" href="https://gitee.com/yadong.zhang/JustAuth/blob/master/LICENSE">
<img src="https://img.shields.io/apm/l/vim-mode.svg?color=yellow" ></img>
@@ -14,9 +14,6 @@
<a target="_blank" href="https://www.oracle.com/technetwork/java/javase/downloads/index.html">
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" ></img>
</a>
<a target="_blank" href="https://apidoc.gitee.com/yadong.zhang/JustAuth/" title="API文档">
<img src="https://img.shields.io/badge/Api%20Docs-1.16.1-orange" ></img>
</a>
<a target="_blank" href="https://justauth.wiki" title="参考文档">
<img src="https://img.shields.io/badge/Docs-latest-blueviolet.svg" ></img>
</a>
@@ -69,7 +66,7 @@ JustAuth 集成了诸如Github、Gitee、支付宝、新浪微博、微信、
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.16.1</version>
<version>1.16.2</version>
</dependency>
```
- 调用api
@@ -123,7 +120,7 @@ authRequest.login(callback);
感谢以下赞助商的支持:
<a href="https://www.duohui.cn?utm_source=justauth" target="_blank"><img src="https://docs.duohui.cn/brand_source/img/std.svg" alt="多会 - 专业活动管理系统" style="height: 54px;" height="54px" /></a>
[我要赞助](https://justauth.wiki/sponsor.html)
## JustAuth 的用户
有很多公司、组织和个人把 JustAuth 用于学习、研究、生产环境和商业产品中,包括(但不限于):
@@ -133,20 +130,24 @@ authRequest.login(callback);
怎么没有我?[登记](https://gitee.com/yadong.zhang/JustAuth/issues/IZ2T7)
## 开源推荐
- `JAP` 开源的登录认证中间件: [https://gitee.com/fujieid/jap](https://gitee.com/fujieid/jap)
- `spring-boot-demo` 深度学习并实战 spring boot 的项目: [https://github.com/xkcoding/spring-boot-demo](https://github.com/xkcoding/spring-boot-demo)
- `mica` SpringBoot 微服务高效开发工具集: [https://github.com/lets-mica/mica](https://github.com/lets-mica/mica)
- `pig` 微服务认证授权脚手架(架构师必备): [https://gitee.com/log4j/pig](https://gitee.com/log4j/pig)
- `SpringBlade` 完整的线上解决方案(企业开发必备): [https://gitee.com/smallc/SpringBlade](https://gitee.com/smallc/SpringBlade)
- `MaxKey` 马克思的钥匙,寓意是最大钥匙,是用户单点登录认证系统Sigle Sign On System,OAuth 2.0/OpenID Connect、SAML 2.0、JWT、CAS等标准化的开放协议使用JustAuth集成OAuth第三方认证。: [https://shimingxy.github.io/MaxKey/](https://shimingxy.github.io/MaxKey/)
- `YurunOAuthLogin` PHP 第三方登录授权 SDK[YurunOAuthLogin](https://gitee.com/yurunsoft/YurunOAuthLogin)
- `sureness` 面向restful api的高性能认证鉴权框架[sureness](https://github.com/usthe/sureness)
更多推荐,请参考:[JustAuth - 开源推荐](https://justauth.wiki)
## 鸣谢
- 感谢 JetBrains 提供的免费开源 License
<p>
<img src="https://images.gitee.com/uploads/images/2020/0406/220236_f5275c90_5531506.png" alt="图片引用自lets-mica" style="float:left;">
</p>
## 其他
- [CONTRIBUTORS](https://justauth.wiki/contributors.html)
- [CHANGELOGS](https://justauth.wiki/update.html)
- [PLAN](https://gitee.com/yadong.zhang/JustAuth/issues/IUGRK)

View File

@@ -1 +1 @@
1.16.1
1.16.2

View File

@@ -6,7 +6,7 @@
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.16.1</version>
<version>1.16.2</version>
<name>JustAuth</name>
<url>https://gitee.com/yadong.zhang/JustAuth</url>

View File

@@ -744,7 +744,7 @@ public enum AuthDefaultSource implements AuthSource {
@Override
public String userInfo() {
return "https://api.twitter.com/1.1/users/show.json";
return "https://api.twitter.com/1.1/account/verify_credentials.json";
}
},
@@ -976,4 +976,25 @@ public enum AuthDefaultSource implements AuthSource {
return "https://%s.okta.com/oauth2/%s/v1/revoke";
}
},
/**
* 程序员客栈
*
* @since 1.16.2
*/
PROGINN {
@Override
public String authorize() {
return "https://www.proginn.com/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://www.proginn.com/oauth2/access_token";
}
@Override
public String userInfo() {
return "https://www.proginn.com/openapi/user/basic_info";
}
},
}

View File

@@ -0,0 +1,33 @@
package me.zhyd.oauth.enums.scope;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Gitee 平台 OAuth 授权范围
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0.0
* @since 1.0.0
*/
@Getter
@AllArgsConstructor
public enum AuthProginnScope implements AuthScope {
/**
* {@code scope} 含义,以{@code description} 为准
*/
BASIC("basic", "访问用户的基本信息", true),
/**
* 以上 scope 需要单独向程序员客栈平台申请,否则不可使用
*/
email("email", "获取用户的邮箱", false),
realname("realname", "获取用户的真实姓名", false),
cellphone("cellphone", "获取用户的手机号码", false),
;
private final String scope;
private final String description;
private final boolean isDefault;
}

View File

@@ -35,7 +35,7 @@ public abstract class AbstractAuthWeChatEnterpriseRequest extends AuthDefaultReq
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
String response = doGetAuthorizationCode(accessTokenUrl(authCallback.getCode()));
String response = doGetAuthorizationCode(accessTokenUrl(null));
JSONObject object = this.checkResponse(response);

View File

@@ -0,0 +1,97 @@
package me.zhyd.oauth.request;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.enums.scope.AuthProginnScope;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.AuthScopeUtils;
import me.zhyd.oauth.utils.HttpUtils;
import me.zhyd.oauth.utils.UrlBuilder;
import java.util.HashMap;
import java.util.Map;
/**
* 程序员客栈
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @since 1.16.2
*/
public class AuthProginnRequest extends AuthDefaultRequest {
public AuthProginnRequest(AuthConfig config) {
super(config, AuthDefaultSource.PROGINN);
}
public AuthProginnRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.PROGINN, authStateCache);
}
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
Map<String, String> params = new HashMap<>();
params.put("code", authCallback.getCode());
params.put("client_id", config.getClientId());
params.put("client_secret", config.getClientSecret());
params.put("grant_type", "authorization_code");
params.put("redirect_uri", config.getRedirectUri());
String response = new HttpUtils(config.getHttpConfig()).post(AuthDefaultSource.PROGINN.accessToken(), params, false);
JSONObject accessTokenObject = JSONObject.parseObject(response);
this.checkResponse(accessTokenObject);
return AuthToken.builder()
.accessToken(accessTokenObject.getString("access_token"))
.refreshToken(accessTokenObject.getString("refresh_token"))
.uid(accessTokenObject.getString("uid"))
.tokenType(accessTokenObject.getString("token_type"))
.expireIn(accessTokenObject.getIntValue("expires_in"))
.build();
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
String userInfo = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(userInfo);
this.checkResponse(object);
return AuthUser.builder()
.rawUserInfo(object)
.uuid(object.getString("uid"))
.username(object.getString("nickname"))
.nickname(object.getString("nickname"))
.avatar(object.getString("avatar"))
.email(object.getString("email"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source.toString())
.build();
}
/**
* 检查响应内容是否正确
*
* @param object 请求响应内容
*/
private void checkResponse(JSONObject object) {
if (object.containsKey("error")) {
throw new AuthException(object.getString("error_description"));
}
}
/**
* 返回带{@code state}参数的授权url授权回调时会带上这个{@code state}
*
* @param state state 验证授权流程的参数可以防止csrf
* @return 返回授权地址
*/
@Override
public String authorize(String state) {
return UrlBuilder.fromBaseUrl(super.authorize(state))
.queryParam("scope", this.getScopes(" ", true, AuthScopeUtils.getDefaultScopes(AuthProginnScope.values())))
.build();
}
}

View File

@@ -4,12 +4,16 @@ import com.alibaba.fastjson.JSONObject;
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.GlobalAuthUtils;
import me.zhyd.oauth.utils.HttpUtils;
import me.zhyd.oauth.utils.StringUtils;
import me.zhyd.oauth.utils.UrlBuilder;
/**
@@ -33,6 +37,26 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
return AuthToken.builder().accessCode(authCallback.getCode()).build();
}
private AuthToken getAuthToken(JSONObject object) {
this.checkResponse(object);
return AuthToken.builder()
.accessToken(object.getString("access_token"))
.expireIn(object.getIntValue("expires_in"))
.tokenType(object.getString("token_type"))
.idToken(object.getString("id_token"))
.refreshToken(object.getString("refresh_token"))
.uid(object.getString("taobao_user_id"))
.openId(object.getString("taobao_open_uid"))
.build();
}
private void checkResponse(JSONObject object) {
if (object.containsKey("error")) {
throw new AuthException(object.getString("error_description"));
}
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
String response = doPostAuthorizationCode(authToken.getAccessCode());
@@ -40,16 +64,12 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
if (accessTokenObject.containsKey("error")) {
throw new AuthException(accessTokenObject.getString("error_description"));
}
authToken.setAccessToken(accessTokenObject.getString("access_token"));
authToken.setRefreshToken(accessTokenObject.getString("refresh_token"));
authToken.setExpireIn(accessTokenObject.getIntValue("expires_in"));
authToken.setUid(accessTokenObject.getString("taobao_user_id"));
authToken.setOpenId(accessTokenObject.getString("taobao_open_uid"));
authToken = this.getAuthToken(accessTokenObject);
String nick = GlobalAuthUtils.urlDecode(accessTokenObject.getString("taobao_user_nick"));
return AuthUser.builder()
.rawUserInfo(new JSONObject())
.uuid(accessTokenObject.getString("taobao_user_id"))
.rawUserInfo(accessTokenObject)
.uuid(StringUtils.isEmpty(authToken.getUid()) ? authToken.getOpenId() : authToken.getUid())
.username(nick)
.nickname(nick)
.gender(AuthUserGender.UNKNOWN)
@@ -58,6 +78,17 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
.build();
}
@Override
public AuthResponse refresh(AuthToken oldToken) {
String tokenUrl = refreshTokenUrl(oldToken.getRefreshToken());
String response = new HttpUtils(config.getHttpConfig()).post(tokenUrl);
JSONObject accessTokenObject = JSONObject.parseObject(response);
return AuthResponse.builder()
.code(AuthResponseStatus.SUCCESS.getCode())
.data(this.getAuthToken(accessTokenObject))
.build();
}
/**
* 返回带{@code state}参数的授权url授权回调时会带上这个{@code state}
*

View File

@@ -1,7 +1,6 @@
package me.zhyd.oauth.request;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.utils.HttpUtils;
import com.xkcoding.http.constants.Constants;
import com.xkcoding.http.support.HttpHeader;
import com.xkcoding.http.util.MapUtil;
@@ -11,6 +10,7 @@ import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtils;
import me.zhyd.oauth.utils.HttpUtils;
import me.zhyd.oauth.utils.UrlBuilder;
import java.util.HashMap;
@@ -47,7 +47,7 @@ public class AuthTwitterRequest extends AuthDefaultRequest {
*/
@Override
public String authorize(String state) {
AuthToken token = this.getRequestToken();
AuthToken token = this.getRequestToken();
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("oauth_token", token.getOauthToken())
.build();
@@ -119,17 +119,15 @@ public class AuthTwitterRequest extends AuthDefaultRequest {
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
Map<String, String> queryParams = new HashMap<>(5);
queryParams.put("user_id", authToken.getUserId());
queryParams.put("screen_name", authToken.getScreenName());
queryParams.put("include_entities", Boolean.toString(true));
queryParams.put("include_email", Boolean.toString(true));
Map<String, String> oauthParams = buildOauthParams();
oauthParams.put("oauth_token", authToken.getOauthToken());
Map<String, String> params = new HashMap<>(oauthParams);
params.putAll(queryParams);
oauthParams.put("oauth_signature", generateTwitterSignature(params, "GET", source.userInfo(), config.getClientSecret(), authToken
.getOauthTokenSecret()));
oauthParams.put("oauth_signature", generateTwitterSignature(params, "GET", source.userInfo(), config.getClientSecret(), authToken.getOauthTokenSecret()));
String header = buildHeader(oauthParams);
HttpHeader httpHeader = new HttpHeader();
@@ -147,6 +145,7 @@ public class AuthTwitterRequest extends AuthDefaultRequest {
.blog(userInfo.getString("url"))
.location(userInfo.getString("location"))
.avatar(userInfo.getString("profile_image_url"))
.email(userInfo.getString("email"))
.source(source.toString())
.token(authToken)
.build();
@@ -155,9 +154,8 @@ public class AuthTwitterRequest extends AuthDefaultRequest {
@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)
.queryParam("include_email", true)
.build();
}