1
0
mirror of synced 2026-05-22 21:53:18 +00:00

Compare commits

..

27 Commits

Author SHA1 Message Date
yadong.zhang fdc78212ff 🍻 文档 2019-09-17 18:38:35 +08:00
yadong.zhang 51087658a4 🍻 完善饿了么授权登录 2019-09-11 19:46:16 +08:00
yadong.zhang 6567f17513 Merge branch 'master' into dev 2019-09-11 15:06:38 +08:00
yadong.zhang 6a3e061921 🍻 错别字 2019-09-11 11:18:35 +08:00
yadong.zhang 3a5a312b68 📝 编写文档 2019-09-11 11:16:31 +08:00
yadong.zhang 3ff0b36b49 Merge branch 'master' into dev 2019-09-11 09:20:10 +08:00
yadong.zhang faae8816be 🍻 添加Nutzboot版Demo 2019-09-11 09:10:41 +08:00
yadong.zhang 6cf6a7d7dc Merge branch 'master' of https://gitee.com/yadong.zhang/JustAuth 2019-09-11 09:07:04 +08:00
yadong.zhang c424f9c9c0 !6 添加Nutzboot版本的Demo地址
Merge pull request !6 from 蛋蛋的忧伤/master
2019-09-10 20:17:55 +08:00
王庆华 726018031f add: 添加NutzBoot版本的Demo,修改README 2019-09-10 19:28:56 +08:00
yadong.zhang 80f2dbdad7 提取公共的Source接口,支持自定义扩展第三方平台的授权登录,具体扩展例子可参考AuthExtendRequest 2019-09-06 22:21:35 +08:00
yadong.zhang 02f9f833e6 提取公共的Source接口,支持自定义扩展第三方平台的授权登录,具体扩展例子可参考AuthExtendRequest 2019-09-06 22:19:02 +08:00
yadong.zhang 05374e7a1f 集成“饿了么”授权登录(未测试) 2019-09-06 19:22:49 +08:00
yadong.zhang 1eacc41959 📝 编写文档 2019-09-06 16:56:29 +08:00
yadong.zhang 66c7455d30 集成美团,待发布1.12.0 2019-09-06 16:54:08 +08:00
yadong.zhang 055807d75f !5 fix: Fastjson < 1.2.60 远程拒绝服务漏洞预警
Merge pull request !5 from harrylee/master
2019-09-06 13:18:52 +08:00
harrylee 9b4e149953 fix: Fastjson < 1.2.60 远程拒绝服务漏洞预警
link: https://card.weibo.com/article/m/show/id/2309404413257925394542
2019-09-06 11:27:55 +08:00
yadong.zhang 2e16556968 📝 编写文档 2019-09-04 09:44:14 +08:00
yadong.zhang c94b123a4b 集成Gitlab 2019-09-03 20:39:19 +08:00
yadong.zhang ee1b6c8c5f 集成酷家乐 2019-09-03 09:14:50 +08:00
yadong.zhang 2be048ef0e Merge pull request #45 from wuweiqi1993/kujialeAuth
Kujiale auth
2019-09-02 21:29:16 +08:00
shahuang 55fd335511 Merge branch 'kujialeAuth' of https://github.com/wuweiqi1993/JustAuth into kujialeAuth 2019-09-02 11:25:40 +08:00
shahuang bb975f8eb3 移除用户额外信息 2019-09-02 11:24:59 +08:00
wuweiqi1993 13a388fb0f Update README.md 2019-08-30 16:37:29 +08:00
wuweiqi1993 ff48e107c8 Update README.md 2019-08-30 16:36:21 +08:00
shahuang de273d0482 add kujiale auth 2019-08-30 16:28:43 +08:00
yadong.zhang 16f77ec770 📝 编写文档 2019-08-23 20:05:26 +08:00
62 changed files with 2456 additions and 808 deletions
+5 -5
View File
@@ -1,15 +1,15 @@
[ ] 是否为解决Issue
- [ ] 是否为解决Issue
### 您做了哪些更新?
#### 新增
- 新增
#### 修改
- 修改
#### 修复
- 修复
#### 其他
- 其他
### 是否做了充分测试?
+188
View File
@@ -0,0 +1,188 @@
<p align="center">
<a href="https://docs.justauth.whnb.wang"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/logo.png" width="400"></a>
</p>
<p align="center">
<strong>Login, so easy.</strong>
</p>
<p align="center">
<a target="_blank" href="https://search.maven.org/search?q=JustAuth">
<img src="https://img.shields.io/badge/Maven Central-1.12.0-blue.svg" ></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>
</a>
<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 Docs-1.12.0-orange.svg" ></img>
</a>
<a target="_blank" href="https://docs.justauth.whnb.wang" title="参考文档">
<img src="https://img.shields.io/badge/Docs-latest-blueviolet.svg" ></img>
</a>
<a href="https://codecov.io/gh/zhangyd-c/JustAuth">
<img src="https://codecov.io/gh/zhangyd-c/JustAuth/branch/master/graph/badge.svg" />
</a>
<a href='https://gitee.com/yadong.zhang/JustAuth/stargazers'>
<img src='https://gitee.com/yadong.zhang/JustAuth/badge/star.svg?theme=white' alt='star'></img>
</a>
<a target="_blank" href='https://github.com/zhangyd-c/JustAuth'>
<img src="https://img.shields.io/github/stars/zhangyd-c/JustAuth.svg?style=social" alt="github star"></img>
</a>
</p>
<center>
<table>
<tr>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitee.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/github.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/dingtalk.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/baidu.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/coding.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/tencentCloud.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/oschina.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/alipay.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/douyin.png" width="20"></td>
</tr>
</table>
<table>
<tr>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/linkedin.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/microsoft.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/mi.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/toutiao.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/teambition.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/renren.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/pinterest.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/stackoverflow.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信企业版"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/csdn.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/kujiale.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitlab.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/meituan.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/eleme.png" width="20"></td>
</tr>
</table>
</center>
-------------------------------------------------------------------------------
`JustAuth`, as you see, It is just a Java library of third-party authorized login, It's smaller and easier to use. JustAuth is the best third-party login tool written in JAVA.
Source Code[gitee](https://gitee.com/yadong.zhang/JustAuth) | [github](https://github.com/zhangyd-c/JustAuth)
Docs[Reference Doc](https://docs.justauth.whnb.wang)
## Features
1. **Multiple platform**: Has integrated more than a dozen third-party platforms.
2. **Minimalist**: The minimalist design is very simple to use.
## Quick start
- Add maven dependency
These artifacts are available from Maven Central:
```xml
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>${latest.version}</version>
</dependency>
```
- Using JustAuth
```java
// Create authorization request
AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()
.clientId("clientId")
.clientSecret("clientSecret")
.redirectUri("redirectUri")
.build());
// Generate authorization url
authRequest.authorize("state");
// After authorization to login, it will return: code(auth_code(Alipay only)),state, After version 1.8.0, you can use the AuthCallback as a parameter to the callback interface
// Note: JustAuth saves state for 3 minutes by default. If it is not used within 3 minutes, the expired state will be cleared automatically.
authRequest.login(callback);
```
**Examples**
- [Springboot Example](https://gitee.com/yadong.zhang/JustAuth-demo)
- [jFinal Example](https://github.com/xkcoding/jfinal-justauth-demo): by [xkcoding](https://github.com/xkcoding)
- [ActFramework Example](https://github.com/xkcoding/act-justauth-demo): by [xkcoding](https://github.com/xkcoding)
- [Nutzboot版](https://github.com/EggsBlue/nutzboot-justauth-demo): by [蛋蛋](https://github.com/EggsBlue)
**Springboot Starter**
- [justauth-spring-boot-starter](https://github.com/xkcoding/justauth-spring-boot-starter): Spring Boot integrates best practices with JustAuth by [xkcoding](https://github.com/xkcoding)
#### API
| :computer: platform | :coffee: API | :page_facing_up: Official document |
|:------:|:-------:|:-------:|
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitee.png" width="20"> | [AuthGiteeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://gitee.com/api/v5/oauth_doc#list_1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/github.png" width="20"> | [AuthGithubRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"> | [AuthWeiboRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/dingtalk.png" width="20"> | [AuthDingTalkRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java) | <a href="https://open-doc.dingtalk.com/microapp/serverapi2/kymkv6" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/baidu.png" width="20"> | [AuthBaiduRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java) | <a href="http://developer.baidu.com/wiki/index.php?title=docs/oauth" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/coding.png" width="25"> | [AuthCodingRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java) | <a href="https://open.coding.net/references/oauth/" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/tencentCloud.png" width="25"> | [AuthTencentCloudRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java) | <a href="https://dev.tencent.com/help/doc/faq/b4e5b7aee786/oauth" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/oschina.png" width="20"> | [AuthOschinaRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java) | <a href="https://www.oschina.net/openapi/docs/oauth2_authorize" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/alipay.png" width="20"> | [AuthAlipayRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java) | <a href="https://alipay.open.taobao.com/docs/doc.htm?spm=a219a.7629140.0.0.336d4b70GUKXOl&treeId=193&articleId=105809&docType=1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"> | [AuthQqRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java) | <a href="https://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8authorization_code%E8%8E%B7%E5%8F%96access_token" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java) | <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"> | [AuthTaobaoRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java) | <a href="https://open.taobao.com/doc.htm?spm=a219a.7386797.0.0.4e00669acnkQy6&source=search&docId=105590&docType=1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"> | [AuthGoogleRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java) | <a href="https://developers.google.com/identity/protocols/OpenIDConnect" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"> | [AuthFacebookRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java) | <a href="https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/douyin.png" width="20"> | [AuthDouyinRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java) | <a href="https://www.douyin.com/platform/doc/m-2-1-1" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/linkedin.png" width="20"> | [AuthLinkedinRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthLinkedinRequest.java) | <a href="https://docs.microsoft.com/zh-cn/linkedin/shared/authentication/authorization-code-flow?context=linkedin/context" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/microsoft.png" width="20"> | [AuthMicrosoftRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMicrosoftRequest.java) | <a href="https://docs.microsoft.com/zh-cn/graph/auth/" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/mi.png" width="20"> | [AuthMiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMiRequest.java) | <a href="https://dev.mi.com/console/doc/detail?pId=711" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/toutiao.png" width="20"> | [AuthToutiaoRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java) | <a href="https://open.mp.toutiao.com/#/resource?_k=y7mfgk" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/teambition.png" width="20"> | [AuthTeambitionRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthTeambitionRequest.java) | <a href="https://docs.teambition.com/" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/renren.png" width="20"> | [AuthRenrenRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthRenrenRequest.java) | <a href="http://open.renren.com/wiki/OAuth2.0" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/pinterest.png" width="20"> | [AuthPinterestRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java) | <a href="https://developers.pinterest.com/docs/api/overview/?" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/stackoverflow.png" width="20"> | [AuthStackOverflowRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java) | <a href="https://api.stackexchange.com/docs/authentication" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png" width="20"> | [AuthHuaweiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java) | <a href="https://developer.huawei.com/consumer/cn/devservice/doc/30101" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | <a href="https://open.work.weixin.qq.com/api/doc#90000/90135/90664" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/kujiale.png" width="20"> | [AuthKujialeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java) | <a href="https://open.kujiale.com/open/apps/2/docs?doc_id=95" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitlab.png" width="20"> | [AuthGitlabRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGitlabRequest.java) | <a href="https://docs.gitlab.com/ee/api/oauth2.html" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/meituan.png" width="20"> | [AuthMeituanRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMeituanRequest.java) | <a href="http://open.waimai.meituan.com/openapi_docs/oauth/" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/eleme.png" width="20"> | [AuthElemeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthElemeRequest.java) | <a href="https://open.shop.ele.me/openapi/documents/khd001" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/csdn.png" width="20"> | [AuthCsdnRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java) | 无 |
## Contributions
1. Fork this project to your repository
2. Clone the project after fork.
3. Modify the code (either to fix issue, or to add new features)
4. Commit and push code to a remote repository
5. Create a new PR (pull request), and select `dev` branch
6. Waiting for author to merge
I look forward to your joining us.
## Contributors
[contributors](https://docs.justauth.whnb.wang/#/contributors)
## Recommend
- `spring-boot-demo` In-depth study and actual combat of spring boot projects: [https://github.com/xkcoding/spring-boot-demo](https://github.com/xkcoding/spring-boot-demo)
- `mica` Efficient Development of scaffolding by Spring Cloud: [https://github.com/lets-mica/mica](https://github.com/lets-mica/mica)
- `pig` Cosmic strongest Micro Services Certified authorized scaffolding (essential for Architects): [https://gitee.com/log4j/pig](https://gitee.com/log4j/pig)
- `SpringBlade` Complete online solution (necessary for enterprise development): https://gitee.com/smallc/SpringBlade
## References
- [The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749)
- [OAuth 2.0](https://oauth.net/2/)
+60 -46
View File
@@ -1,12 +1,12 @@
<p align="center">
<a href="https://www.justauth.cn/"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/logo.png" width="400"></a>
<a href="https://docs.justauth.whnb.wang"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/logo.png" width="400"></a>
</p>
<p align="center">
<strong>Login, so easy.</strong>
</p>
<p align="center">
<a target="_blank" href="https://search.maven.org/search?q=JustAuth">
<img src="https://img.shields.io/badge/Maven Central-1.10.1-blue.svg" ></img>
<img src="https://img.shields.io/badge/Maven Central-1.12.0-blue.svg" ></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>
@@ -15,7 +15,7 @@
<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 Docs-1.10.1-orange.svg" ></img>
<img src="https://img.shields.io/badge/Api Docs-1.12.0-orange.svg" ></img>
</a>
<a target="_blank" href="https://docs.justauth.whnb.wang" title="参考文档">
<img src="https://img.shields.io/badge/Docs-latest-blueviolet.svg" ></img>
@@ -34,36 +34,40 @@
<center>
<table>
<tr>
<td align="center" width="200"><a href="#授权gitee"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitee.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权github"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/github.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权weibo"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权钉钉"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/dingtalk.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权百度"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/baidu.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权coding"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/coding.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权腾讯云开发者平台"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/tencentCloud.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权oschina"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/oschina.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权支付宝"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/alipay.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权qq"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权微信"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权淘宝"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权google"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权facebook"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权抖音"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/douyin.png" width="20"></a></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitee.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/github.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/dingtalk.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/baidu.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/coding.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/tencentCloud.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/oschina.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/alipay.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/qq.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/douyin.png" width="20"></td>
</tr>
</table>
<table>
<tr>
<td align="center" width="200"><a href="#授权领英"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/linkedin.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权微软"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/microsoft.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权小米"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/mi.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权今日头条"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/toutiao.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权Teambition"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/teambition.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权人人"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/renren.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权Pinterest"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/pinterest.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权Stack Overflow"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/stackoverflow.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权华为"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权微信企业版" title="微信企业版"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"></a></td>
<td align="center" width="200"><a href="#授权csdn"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/csdn.png" width="20"></a></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/linkedin.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/microsoft.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/mi.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/toutiao.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/teambition.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/renren.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/pinterest.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/stackoverflow.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20" title="微信企业版"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/csdn.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/kujiale.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitlab.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/meituan.png" width="20"></td>
<td align="center" width="200"><img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/eleme.png" width="20"></td>
</tr>
</table>
</center>
@@ -91,7 +95,7 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.10.1</version>
<version>1.12.0</version>
</dependency>
```
- 调用api
@@ -103,7 +107,7 @@ AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()
.redirectUri("redirectUri")
.build());
// 生成授权页面
authRequest.authorize();
authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state1.8.0版本后,可以用AuthCallback类作为回调接口的参数
// 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(callback);
@@ -111,16 +115,12 @@ authRequest.login(callback);
**配套Demo**
- [Springboot版](https://gitee.com/yadong.zhang/JustAuth-demo)
- [jFinal版](https://github.com/xkcoding/jfinal-justauth-demo)
- [ActFramework版](https://github.com/xkcoding/act-justauth-demo)
- [jFinal版](https://github.com/xkcoding/jfinal-justauth-demo): Jfinal集成JustAuth的demo by [xkcoding](https://github.com/xkcoding)
- [ActFramework版](https://github.com/xkcoding/act-justauth-demo): ActFramework 集成 JustAuth 的 demo by [xkcoding](https://github.com/xkcoding)
- [Nutzboot版](https://github.com/EggsBlue/nutzboot-justauth-demo): NutzBoot集成JustAuth的demo by [蛋蛋](https://github.com/EggsBlue)
**扩展工具**
- [justauth-spring-boot-starter](https://github.com/xkcoding/justauth-spring-boot-starter): Spring Boot 集成 JustAuth 的最佳实践
**配套SpringBoot starter**
[justauth-spring-boot-starter](https://github.com/xkcoding/justauth-spring-boot-starter)
## 插件
- [justauth-spring-boot-starter](https://github.com/xkcoding/justauth-spring-boot-starter): Spring Boot 集成 JustAuth 的最佳实践 by [xkcoding](https://github.com/xkcoding)
具体的例子可以参考:
@@ -156,6 +156,10 @@ authRequest.login(callback);
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/stackoverflow.png" width="20"> | [AuthStackOverflowRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java) | <a href="https://api.stackexchange.com/docs/authentication" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png" width="20"> | [AuthHuaweiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java) | <a href="https://developer.huawei.com/consumer/cn/devservice/doc/30101" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | <a href="https://open.work.weixin.qq.com/api/doc#90000/90135/90664" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/kujiale.png" width="20"> | [AuthKujialeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java) | <a href="https://open.kujiale.com/open/apps/2/docs?doc_id=95" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitlab.png" width="20"> | [AuthGitlabRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGitlabRequest.java) | <a href="https://docs.gitlab.com/ee/api/oauth2.html" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/meituan.png" width="20"> | [AuthMeituanRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMeituanRequest.java) | <a href="http://open.waimai.meituan.com/openapi_docs/oauth/" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/eleme.png" width="20"> | [AuthElemeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthElemeRequest.java) | <a href="https://open.shop.ele.me/openapi/documents/khd001" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/csdn.png" width="20"> | [AuthCsdnRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java) | 无 |
_请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经下线。如果以前申请过的应用,可以继续使用,但是不再支持申请新的应用。so, 本项目中的CSDN登录只能针对少部分用户使用了_
@@ -175,19 +179,30 @@ _请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经
5. 发起PRpull request 请求,提交到`dev`分支
6. 等待作者合并
## 贡献者名单
[contributors](https://docs.justauth.whnb.wang/#/contributors)
## 致谢
在项目立项初期,也对当前开源圈的一些相同类型的项目作过调研,同时本项目也参考过这些项目,再次感谢开源圈内的朋友。
[YurunOAuthLogin](https://gitee.com/yurunsoft/YurunOAuthLogin): PHP 第三方登录授权 SDK
- [YurunOAuthLogin](https://gitee.com/yurunsoft/YurunOAuthLogin): PHP 第三方登录授权 SDK
- [阿里妈妈MUX倾力打造的矢量图标库-iconfont](https://www.iconfont.cn/search/index): 本文档中的图标大部分取自该平台
- [mica](https://github.com/lets-mica/mica)Spring Cloud 微服务开发核心包,支持 `web ``webflux`。注:JustAuth项目中的[UuidUtils](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/utils/UuidUtils.java)就是直接使用的mica提供的高性能的uuid创建工具类源码[StringUtil.java](https://github.com/lets-mica/mica/blob/master/mica-core/src/main/java/net/dreamlu/mica/core/utils/StringUtil.java#L335)
- 感谢 JetBrains 提供的免费开源 License
<img src="https://github.com/lets-mica/mica/raw/c251e176b81518a6a570bf4eb21f525c4f582a81/docs/img/jetbrains.png" alt="图片引用自lets-mica" style="float:left;">
[阿里妈妈MUX倾力打造的矢量图标库-iconfont](https://www.iconfont.cn/search/index): 本文档中的图标大部分取自该平台
[mica](https://github.com/lets-mica/mica)Spring Cloud 微服务开发核心包,支持 `web ``webflux`。注:JustAuth项目中的[UuidUtils](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/utils/UuidUtils.java)就是直接使用的mica提供的高性能的uuid创建工具类源码[StringUtil.java](https://github.com/lets-mica/mica/blob/master/mica-core/src/main/java/net/dreamlu/mica/core/utils/StringUtil.java#L335)
## 开源推荐
- `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
## 关于OAuth
[The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749)
- [The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749)
- [OAuth 2.0](https://oauth.net/2/)
## 关注&交流
@@ -201,7 +216,6 @@ _请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经
- 开源总群 (190886500):各个开源项目的都有,也有博客建设等方面的朋友。
## 请喝咖啡
| 支付宝 | 微信 |
-7
View File
@@ -1,7 +0,0 @@
# 项目贡献者名单
- <img src="https://avatar.gitee.com/uploads/99/784199_yadong.zhang.png!avatar100?1462325358" width="20"> · yadong.zhang : <a href="https://github.com/zhangyd-c" target="_blank">[Github]</a> | <a href="https://gitee.com/yadong.zhang" target="_blank">[Gitee]</a> | <a href="https://www.zhyd.me" target="_blank">[个人网站]</a>
- <img src="https://avatars0.githubusercontent.com/u/10429917?s=460&v=4" width="20"> · yangkai.shen : <a href="https://github.com/xkcoding" target="_blank">[Github]</a> | <a href="https://xkcoding.com" target="_blank">[个人网站]</a>
- <img src="https://avatar.gitee.com/uploads/51/1651_dolphinboy.png!avatar100?1479346570" width="20"> · skqing : <a href="https://gitee.com/skqing" target="_blank">[Gitee]</a> | <a href="https://my.oschina.net/dolphinboy" target="_blank">[个人网站]</a>
- <img src="https://avatars2.githubusercontent.com/u/2988765?s=115&v=4" width="20"> · pengisgood : <a href="https://github.com/pengisgood" target="_blank">[Github]</a> | <a href="https://pengisgood.github.io" target="_blank">[个人网站]</a>
- 千年等一回,我只为等你...
+44 -12
View File
@@ -1,5 +1,5 @@
<p align="center">
<a href="https://www.justauth.cn/"><img src="./_media/cover.png" width="400"></a>
<a href="https://docs.justauth.whnb.wang"><img src="./_media/cover.png" width="400"></a>
</p>
<p align="center">
<strong>Login, so easy!</strong>
@@ -9,7 +9,7 @@
</p>
<p align="center">
<a target="_blank" href="https://search.maven.org/search?q=JustAuth">
<img src="https://img.shields.io/badge/Maven Central-1.10.1-blue.svg" ></img>
<img src="https://img.shields.io/badge/Maven Central-1.12.0-blue.svg" ></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>
@@ -18,7 +18,7 @@
<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 Docs-1.10.1-orange.svg" ></img>
<img src="https://img.shields.io/badge/Api Docs-1.12.0-orange.svg" ></img>
</a>
<a target="_blank" href="https://docs.justauth.whnb.wang" title="参考文档">
<img src="https://img.shields.io/badge/Docs-latest-blueviolet.svg" ></img>
@@ -54,6 +54,10 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
1. **全**:已集成十多家第三方平台(国内外常用的基本都已包含),后续依然还有扩展计划!
2. **简**:API就是奔着最简单去设计的,尽量让您用起来没有障碍感!
## 项目关注度趋势
[![Stargazers over time](https://starchart.cc/justauth/JustAuth.svg)](https://starchart.cc/justauth/JustAuth)
## 已集成的平台
| :computer: 平台 | :coffee: API类 | :page_facing_up: SDK |
@@ -83,6 +87,10 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/stackoverflow.png" width="20"> | [AuthStackOverflowRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java) | <a href="https://api.stackexchange.com/docs/authentication" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png" width="20"> | [AuthHuaweiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java) | <a href="https://developer.huawei.com/consumer/cn/devservice/doc/30101" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png" width="20"> | [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | <a href="https://open.work.weixin.qq.com/api/doc#90000/90135/90664" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/kujiale.png" width="20"> | [AuthKujialeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java) | <a href="https://open.kujiale.com/open/apps/2/docs?doc_id=95" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitlab.png" width="20"> | [AuthGitlabRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGitlabRequest.java) | <a href="https://docs.gitlab.com/ee/api/oauth2.html" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/meituan.png" width="20"> | [AuthMeituanRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMeituanRequest.java) | <a href="http://open.waimai.meituan.com/openapi_docs/oauth/" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/eleme.png" width="20"> | [AuthElemeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthElemeRequest.java) | <a href="https://open.shop.ele.me/openapi/documents/khd001" target="_blank">参考文档</a> |
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/csdn.png" width="20"> | [AuthCsdnRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java) | 无 |
@@ -93,7 +101,7 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.10.1</version>
<version>${latest.version}</version>
</dependency>
```
- 调用api
@@ -105,29 +113,53 @@ AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()
.redirectUri("redirectUri")
.build());
// 生成授权页面
authRequest.authorize();
authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state1.8.0版本后,可以用AuthCallback类作为回调接口的参数
// 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(callback);
```
## 贡献代码
## 参与&贡献
JustAuth的发展离不开朋友们的支持,时至今日,JustAuth已渐趋完善,但仍有很大的改善空间。欢迎各位朋友为JustAuth贡献一份力量。
### 提供bug或建议
- [Gitee](https://gitee.com/yadong.zhang/JustAuth/issues)
- [Github](https://github.com/justauth/JustAuth/issues)
如果你正在使用JustAuth,可以在这儿留下你的足迹,获得优先推送、曝光
- [Gitee](https://gitee.com/yadong.zhang/JustAuth/issues/IZ2T7)
- [Github](https://github.com/justauth/JustAuth/issues/17)
### 贡献代码的步骤
1. fork本项目到自己的repo
2. 把fork过去的项目也就是你仓库中的项目clone到你本地
3. 修改代码
4. commit后push到自己的库
2. 把fork过去的项目也就是你仓库中的项目clone到你本地
3. 修改代码`dev`分支)
4. commit后push到自己的
5. 发起PRpull request 请求,提交到`dev`分支
6. 等待作者合并
6. 等待合并
_注:JustAuth只接受集成oauth2.0的平台_
### 注意事项
## 关于功能尝鲜
1. JustAuth只接受集成**OAuth2.0**的平台
2. 建议安装“**阿里编码规约**”插件,然后进行开发
3. 提交PR前请格式化好自己的代码
4. 注释规范,自定义的方法一定要加上:方法说明、参数说明、返回值说明等
## 功能尝鲜
JustAuth一共有两个主要分支:
- 线上版分支(master):稳定版,发布版就是这个分支的代码
- 开发版分支(dev):不保证稳定,新功能都会优先推送到该分支,对于想尝鲜的朋友,可以直接下载代码,然后源码编译dev分支
## 开源推荐
- `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
## 捐赠
+1 -1
View File
@@ -1,6 +1,6 @@
![](_media/logo.png)
# JustAuth <small>1.10.1</small>
# JustAuth <small>1.11.0</small>
<strong>史上最全的整合第三方登录的开源库</strong>
+8 -6
View File
@@ -1,12 +1,14 @@
- [入门](README.md)
- [更新记录](update.md)
- 引导
- [如何使用JustAuth集成一个平台](how-to-use.md)
- [获取授权链接](authorize.md)
- [登录](login.md)
- [入门和使用](README.md)
- [贡献者名单](contributors.md)
- 快速开始
- [名词解释](explain.md)
- [OAuth流程](oauth.md)
- [如何使用](how-to-use.md)
- 其他特性
- [使用State](using-state.md)
- [自定义state缓存](customize-the-state-cache.md)
- [配套项目](supporting.md)
- [Q&A](Q&A.md)
- [Who is using](users.md)
- [致谢](thx.md)
- [更新记录](update.md)
-3
View File
@@ -1,3 +0,0 @@
# 获取授权链接
待补充
+31
View File
@@ -0,0 +1,31 @@
# 项目贡献者名单
> 排序不分先后
- <img src="https://avatar.gitee.com/uploads/99/784199_yadong.zhang.png!avatar100?1462325358" width="20"> · yadong.zhang : <a href="https://github.com/zhangyd-c" target="_blank">[Github]</a> | <a href="https://gitee.com/yadong.zhang" target="_blank">[Gitee]</a> | <a href="https://www.zhyd.me" target="_blank">[个人网站]</a>
- <img src="https://avatars0.githubusercontent.com/u/10429917?s=460&v=4" width="20"> · yangkai.shen : <a href="https://github.com/xkcoding" target="_blank">[Github]</a> | <a href="https://xkcoding.com" target="_blank">[个人网站]</a>
- 集成微信登录、QQ登录、Google登录、微软登录、小米登录、企业微信登录
- 优化代码、架构,增加自定义缓存
- 提供jFinal版demo
- 提供ActFramework版demo
- 提供SpringBoot快速集成的justauth-spring-boot-starter
- <img src="https://avatars2.githubusercontent.com/u/2988765?s=115&v=4" width="20"> · pengisgood : <a href="https://github.com/pengisgood" target="_blank">[Github]</a> | <a href="https://pengisgood.github.io" target="_blank">[个人网站]</a>
- 集成人人登录、Pinterest登录、StackOverflow登录
- <img src="https://avatar.gitee.com/uploads/51/1651_dolphinboy.png!avatar100?1479346570" width="20"> · skqing : <a href="https://gitee.com/skqing" target="_blank">[Gitee]</a> | <a href="https://my.oschina.net/dolphinboy" target="_blank">[个人网站]</a>
- 修复钉钉登录的部分问题
- 优化微博登录
- <img src="https://avatars1.githubusercontent.com/u/47110161?s=88&v=4" width="20"> · dyc12ii : <a href="https://github.com/dyc12ii" target="_blank">[Gitee]</a>
- 升级fastjson版本至1.2.58
- <img src="https://gitee.com/uploads/22/4981222_harryleexyz.png?1556524275" width="20"> · harrylee : <a href="https://gitee.com/harryleexyz" target="_blank">[Gitee]</a>
- 升级fastjson依赖到1.2.60
- <img src="https://avatars3.githubusercontent.com/u/32814990?s=460&v=4" width="20"> · Veigar : <a href="https://github.com/wuweiqi1993" target="_blank">[Github]</a>
- 集成酷家乐登录
- <img src="https://avatar.gitee.com/uploads/24/1280924_TopCoderMyDream.png!avatar200?1523763232" width="20"> · 蛋蛋 : <a href="https://gitee.com/TopCoderMyDream" target="_blank">[Gitee]</a> | <a href="https://github.com/EggsBlue" target="_blank">[Github]</a>
- 提供NutzBoot版的demo项目
- <img src="https://avatars0.githubusercontent.com/u/35978114?s=180&v=4" width="20"> · Braavos96 : <a href="https://github.com/Braavos96" target="_blank">[Github]</a>
- 添加测试用例:UrlBuilder 、GlobalAuthUtil
- <img src="https://avatars0.githubusercontent.com/u/283483?s=180&v=4" width="20"> · Chris Smowton : <a href="https://github.com/smowton" target="_blank">[Github]</a>
- 添加测试用例:StringUtils
- 千年等一回,我只为等你...
ps: 如有遗漏,请告知
+29
View File
@@ -0,0 +1,29 @@
本文将就JustAuth中涉及到的一些配置、关键词做一下简单说明,方便使用者理解、使用。
## 本文相关名词
- `开发者` 指使用`JustAuth`的开发者
- `第三方` 指开发者对接的第三方网站,比如:QQ平台、微信平台、微博平台
- `用户` 指最终服务的真实用户
## JustAuth中的关键词
以下内容了解后,将会使你更容易地上手JustAuth。
- `clientId` 客户端身份标识符(应用id),一般在申请完Oauth应用后,由**第三方平台颁发**,唯一
- `clientSecret` 客户端密钥,一般在申请完Oauth应用后,由**第三方平台颁发**
- `redirectUri` **开发者项目中的有效api地址**。用户在确认第三方平台授权(登录)后,第三方平台会重定向到该地址,并携带code等参数
- `state` 用来保持授权会话流程完整性,防止CSRF攻击的安全的随机的参数,由**开发者生成**
- `alipayPublicKey` 支付宝公钥。当选择支付宝登录时,必传该值,由**开发者生成**
- `unionId` 是否需要申请unionid,目前只针对**qq登录**。注:qq授权登录时,获取unionid需要单独发送邮件申请权限。如果个人开发者账号中申请了该权限,可以将该值置为true,在获取openId时就会同步获取unionId。参考链接:[UnionID介绍](http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D)
- `stackOverflowKey` Stack Overflow 登陆时需单独提供的key,由**第三方平台颁发**
- `agentId` 企业微信登陆时需单独提供该值,由**第三方平台颁发**,为授权方的网页应用ID
- `source` JustAuth支持的第三方平台,比如:GITHUB、GITEE等
## 参考资料
关于OAuth2相关的内容、原理可以自行参阅以下资料:
- [The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749)
- [OAuth 2.0](https://oauth.net/2/)
+147 -2
View File
@@ -1,3 +1,148 @@
# 如何使用JustAuth集成一个平台
# 如何使用
待补充
在前面有介绍到,JustAuth的特点之一就是**简**,极简主义,不给使用者造成不必要的障碍。
既然牛皮吹下了, 那么如何才能用JustAuth实现第三方登录呢?
## 使用步骤
使用JustAuth总共分三步(**这三步也适合于JustAuth支持的任何一个平台**):
1. 申请注册第三方平台的开发者账号
2. 创建第三方平台的应用,获取配置信息(`accessKey`, `secretKey`, `redirectUri`)
3. 使用该工具实现授权登陆
## 使用方式
- 引入依赖
```xml
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>${latest.version}</version>
</dependency>
```
- 调用api
```java
// 创建授权request
AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()
.clientId("clientId")
.clientSecret("clientSecret")
.redirectUri("redirectUri")
.build());
// 生成授权页面
authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state1.8.0版本后,可以用AuthCallback类作为回调接口的参数
// 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(callback);
```
## API分解
**JustAuth**的核心就是一个个的`request`,每个平台都对应一个具体的`request`类,所以在使用之前,需要就具体的授权平台创建响应的`request`
```java
// 创建授权request
AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()
.clientId("clientId")
.clientSecret("clientSecret")
.redirectUri("redirectUri")
.build());
```
所有可用的`Request`列表请参考:[已集成的平台](https://docs.justauth.whnb.wang/#/README?id=已集成的平台)
### 获取授权链接
```java
String authorizeUrl = authRequest.authorize("state");
```
获取到`authorizeUrl`后,可以手动实现redirect到`authorizeUrl`
**伪代码**
```java
/**
*
* @param source 第三方授权平台,以本例为参考,该值为gitee(因为上面声明的AuthGiteeRequest
*/
@RequestMapping("/render/{source}")
public void renderAuth(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
AuthRequest authRequest = getAuthRequest(source);
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
response.sendRedirect(authorizeUrl);
}
```
注:`state`建议必传!`state``OAuth`的流程中的主要作用就是保证请求完整性,防止**CSRF**风险,此处传的`state`将在回调时传回
### 登录(获取用户信息)
```java
AuthResponse response = authRequest.login(callback);
```
授权登录后会返回code(auth_code(仅限支付宝)、authorization_code(仅限华为))、state1.8.0版本后,用`AuthCallback`类作为回调接口的入参
**伪代码**
```java
/**
*
* @param source 第三方授权平台,以本例为参考,该值为gitee(因为上面声明的AuthGiteeRequest
*/
@RequestMapping("/callback/{source}")
public Object login(@PathVariable("source") String source, AuthCallback callback) {
AuthRequest authRequest = getAuthRequest(source);
AuthResponse response = authRequest.login(callback);
return response;
}
```
**注:第三方平台中配置的授权回调地址,以本文为例,在创建授权应用时的回调地址应为:`[host]/callback/gitee`**
### 刷新token
注:`refresh`功能,并不是每个平台都支持
```java
AuthResponse response = authRequest.refresh(AuthToken.builder().refreshToken(token).build());
```
**伪代码**
```java
/**
*
* @param source 第三方授权平台,以本例为参考,该值为gitee(因为上面声明的AuthGiteeRequest
* @param token login成功后返回的refreshToken
*/
@RequestMapping("/refresh/{source}")
public Object refreshAuth(@PathVariable("source") String source, String token){
AuthRequest authRequest = getAuthRequest(source);
return authRequest.refresh(AuthToken.builder().refreshToken(token).build());
}
```
### 取消授权
注:`revoke`功能,并不是每个平台都支持
```java
AuthResponse response = authRequest.revoke(AuthToken.builder().accessToken(token).build());
```
**伪代码**
```java
/**
*
* @param source 第三方授权平台,以本例为参考,该值为gitee(因为上面声明的AuthGiteeRequest
* @param token login成功后返回的accessToken
*/
@RequestMapping("/revoke/{source}/{token}")
public Object revokeAuth(@PathVariable("source") String source, @PathVariable("token") String token) throws IOException {
AuthRequest authRequest = getAuthRequest(source);
return authRequest.revoke(AuthToken.builder().accessToken(token).build());
}
```
+23
View File
@@ -48,6 +48,29 @@
auto2top: true,
coverpage: true,
formatUpdated: '{YYYY}/{MM}/{DD} {HH}:{mm}:{ss}',
plugins: [
function (hook, vm) {
var footer = [
'<hr/>',
'<footer>',
'<span>JustAuth: <a href="https://github.com/justauth/JustAuth">Github</a> | <a href="https://gitee.com/yadong.zhang/JustAuth">Gitee</a> &copy;2019.</span>',
'<span>Proudly published with <a href="https://github.com/docsifyjs/docsify" target="_blank">docsify</a>.</span>',
'</footer>'
].join('');
hook.afterEach(function (html) {
return html + footer
});
hook.beforeEach(function (html) {
var url = 'https://gitee.com/yadong.zhang/JustAuth/tree/master/docs/' + vm.route.file;
var editHtml = '[📝 编辑该文档](' + url + ')\n';
return html
+ '\n----\n'
+ 'Last modified {docsify-updated} '
+ editHtml
})
}
]
}
</script>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
-3
View File
@@ -1,3 +0,0 @@
# 登录
待补充
+61
View File
@@ -0,0 +1,61 @@
# 关于OAuth
请先查阅以下资料:
- [The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749)
- [OAuth 2.0](https://oauth.net/2/)
## OAuth 2的授权流程
### 参与的角色
- `Resource Owner` 资源所有者,即代表授权客户端访问本身资源信息的用户(User),也就是应用场景中的“**开发者A**”
- `Resource Server` 资源服务器,托管受保护的**用户账号信息**,比如Github
- `Authorization Server` 授权服务器,**验证用户身份**然后为客户端派发资源访问令牌,比如Github
- `Resource Server``Authorization Server` 可以是同一台服务器,也可以是不同的服务器,视具体的授权平台而有所差异
- `Client` 客户端,即代表意图访问受限资源的**第三方应用**
### 授权流程
```html
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
```
上面的流程图取自[The OAuth 2.0 Authorization Framework#1.2](https://tools.ietf.org/html/rfc6749#section-1.2)
- (A) 用户打开**客户端**以后,**客户端**要求**用户**给予授权。
- (B) **用户**同意给予**客户端**授权。
- (C) **客户端**使用上一步获得的授权,向**认证服务器**申请令牌。
- (D) **认证服务器**对**客户端**进行认证以后,确认无误,同意发放令牌
- (E) **客户端**使用令牌,向**资源服务器**申请获取资源。
- (F) **资源服务器**确认令牌无误,同意向**客户端**开放资源。
### 授权许可 `Authorization Grant`
- Authorization Code
- 结合普通服务器端应用使用(**web**端常用的授权方式)
- Implicit
- 结合移动应用或 Web App 使用
- Resource Owner Password Credentials
- 适用于受信任客户端应用,例如同个组织的内部或外部应用
- Client Credentials
- 适用于客户端调用主服务API型应用(比如百度API Store
`JustAuth`中是使用的`Authorization Code`授权方式,下面将主要讲解`Authorization Code`的授权流程
(未完待续)
+6 -6
View File
@@ -1,8 +1,8 @@
## 配套demo
- [Springboot版](https://gitee.com/yadong.zhang/JustAuth-demo) JustAuth项目的demospringboot项目)
- [jFinal版](https://github.com/xkcoding/jfinal-justauth-demo) Jfinal集成JustAuth的demo
- [ActFramework版](https://github.com/xkcoding/act-justauth-demo) ActFramework 集成 JustAuth 的 demo
**配套Demo**
- [Springboot版](https://gitee.com/yadong.zhang/JustAuth-demo)
- [jFinal版](https://github.com/xkcoding/jfinal-justauth-demo): Jfinal集成JustAuth的demo by [xkcoding](https://github.com/xkcoding)
- [ActFramework版](https://github.com/xkcoding/act-justauth-demo): ActFramework 集成 JustAuth 的 demo by [xkcoding](https://github.com/xkcoding)
- [Nutzboot版](https://github.com/EggsBlue/nutzboot-justauth-demo): NutzBoot集成JustAuth的demo by [蛋蛋](https://github.com/EggsBlue)
## 插件
- [justauth-spring-boot-starter](https://github.com/xkcoding/justauth-spring-boot-starter) Spring Boot 集成 JustAuth 的最佳实践
- [justauth-spring-boot-starter](https://github.com/xkcoding/justauth-spring-boot-starter): Spring Boot 集成 JustAuth 的最佳实践 by [xkcoding](https://github.com/xkcoding)
+15
View File
@@ -0,0 +1,15 @@
# 致谢
在项目立项初期,也对当前开源圈的一些相同类型的项目作过调研,同时本项目也参考过这些项目,再次感谢开源圈内的朋友。
- [YurunOAuthLogin](https://gitee.com/yurunsoft/YurunOAuthLogin): PHP 第三方登录授权 SDK
- [阿里妈妈MUX倾力打造的矢量图标库-iconfont](https://www.iconfont.cn/search/index): 本文档中的图标大部分取自该平台
- [mica](https://github.com/lets-mica/mica)Spring Cloud 微服务开发核心包,支持 `web ``webflux`。注:JustAuth项目中的[UuidUtils](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/utils/UuidUtils.java)就是直接使用的mica提供的高性能的uuid创建工具类源码[StringUtil.java](https://github.com/lets-mica/mica/blob/master/mica-core/src/main/java/net/dreamlu/mica/core/utils/StringUtil.java#L335)
**感谢 JetBrains 提供的免费开源 License**
<img src="https://github.com/lets-mica/mica/raw/c251e176b81518a6a570bf4eb21f525c4f582a81/docs/img/jetbrains.png" alt="图片引用自lets-mica" style="float:left;">
<div style="clear: both;"></div>
+16
View File
@@ -1,3 +1,19 @@
## v1.12.0
### 2019/09/06
- 集成“美团”授权登录
- 集成“饿了么”授权登录
- 升级Fastjson依赖到1.2.60,预防[“Fastjson 1.2.60 远程拒绝服务漏洞预警”](https://card.weibo.com/article/m/show/id/2309404413257925394542)
## v1.11.0
### 2019/09/03
- 集成“Gitlab”授权登录
### 2019/09/02
- 集成“酷家乐”授权登录
## v1.10.1
### 2019/08/17
+51 -1
View File
@@ -1,3 +1,53 @@
# 使用State
待补充
## state使用的流程
在JustAuth中`state`参数的使用流程如下:
1. 获取`authorizeUrl`时创建`state`(开发者创建,如果不创建则系统默认生成)
2. 缓存`state`JustAuth执行)
3. 内置的缓存调度器自动清除已过期的`state`JustAuth执行)
## 创建state(开发者)
`state`在OAuth授权流程中是一个**非必要但很重要**的参数,就如[名词解释](https://docs.justauth.whnb.wang/#/explain?id=justauth中的关键词)中描述的:`state`是用来保持授权会话流程完整性,防止CSRF攻击的安全的随机的参数,**由开发者生成**。
在JustAuth中提供了一个默认的创建state的方法,使用方式:
```java
String state = AuthStateUtils.createState()
```
`createState`的内部实现其实就是生成了一个UUID(采用 jdk 9 的形式,优化性能),该工具是直接copy自[mica](https://github.com/lets-mica/mica/blob/master/mica-core/src/main/java/net/dreamlu/mica/core/utils/StringUtil.java)`mica`是一个SpringBoot微服务高效开发工具集,开源地址:[https://github.com/lets-mica/mica](https://github.com/lets-mica/mica)),关于mica uuid生成方式的压测结果,可以参考:https://github.com/lets-mica/mica-jmh/wiki/uuid。
除此之外,开发者还可以自己生成特定的`state`参数。
## 缓存stateJustAuth
在JustAuth中,内置了一个基于map的state缓存器,默认缓存有效期为3分钟(缓存配置见`AuthCacheConfig.java`)。`AuthCacheConfig`中包含两个配置参数:
- `timeout` 缓存过期时间,默认3分钟
- `schedulePrune` 是否开启定时清理过期state的任务,默认开启。如果不开启,则需要开发者自己对state做处理,防止map存入过多内容
缓存state的操作是在`getRealState`中触发的,不需要开发者自己处理
```java
/**
* 获取state,如果为空, 则默认取当前日期的时间戳
*
* @param state 原始的state
* @return 返回不为null的state
*/
protected String getRealState(String state) {
if (StringUtils.isEmpty(state)) {
state = UuidUtils.getUUID();
}
// 缓存state
authStateCache.cache(state, state);
return state;
}
```
注:关于自定义缓存,请参考下节内容。
## 清理stateJustAuth
JustAuth内置了一个缓存调度器,默认3分钟清理一次过期的`state`,缓存清理时间可以通过`AuthCacheConfig.timeout`进行修改,不建议修改太大。
+4 -3
View File
@@ -6,12 +6,13 @@
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.10.1</version>
<version>1.12.0</version>
<name>JustAuth</name>
<url>https://gitee.com/yadong.zhang/JustAuth</url>
<description>
史上最全的整合第三方登录的工具,目前已支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软和今日头条等第三方平台的授权登录。
史上最全的整合第三方登录的开源库。目前已支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、
QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、企业微信、酷家乐和Gitlab等第三方平台的授权登录。
Login, so easy!
</description>
@@ -61,7 +62,7 @@
<hutool-version>4.6.1</hutool-version>
<lombok-version>1.18.4</lombok-version>
<junit-version>4.11</junit-version>
<fastjson-version>1.2.58</fastjson-version>
<fastjson-version>1.2.60</fastjson-version>
<alipay-sdk-version>3.7.4.ALL</alipay-sdk-version>
<jacoco-version>0.8.2</jacoco-version>
</properties>
@@ -16,12 +16,12 @@ import lombok.*;
public class AuthConfig {
/**
* 客户端id:对应平台的appKey
* 客户端id:对应平台的appKey
*/
private String clientId;
/**
* 客户端Secret:对应平台的appSecret
* 客户端Secret:对应平台的appSecret
*/
private String clientSecret;
@@ -0,0 +1,677 @@
package me.zhyd.oauth.config;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.exception.AuthException;
/**
* JustAuth内置的各api需要的url, 用枚举类分平台类型管理
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @since 1.0
*/
public enum AuthDefaultSource implements AuthSource {
/**
* Github
*/
GITHUB {
@Override
public String authorize() {
return "https://github.com/login/oauth/authorize";
}
@Override
public String accessToken() {
return "https://github.com/login/oauth/access_token";
}
@Override
public String userInfo() {
return "https://api.github.com/user";
}
},
/**
* 新浪微博
*/
WEIBO {
@Override
public String authorize() {
return "https://api.weibo.com/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://api.weibo.com/oauth2/access_token";
}
@Override
public String userInfo() {
return "https://api.weibo.com/2/users/show.json";
}
},
/**
* gitee
*/
GITEE {
@Override
public String authorize() {
return "https://gitee.com/oauth/authorize";
}
@Override
public String accessToken() {
return "https://gitee.com/oauth/token";
}
@Override
public String userInfo() {
return "https://gitee.com/api/v5/user";
}
},
/**
* 钉钉
*/
DINGTALK {
@Override
public String authorize() {
return "https://oapi.dingtalk.com/connect/qrconnect";
}
@Override
public String accessToken() {
throw new AuthException(AuthResponseStatus.UNSUPPORTED);
}
@Override
public String userInfo() {
return "https://oapi.dingtalk.com/sns/getuserinfo_bycode";
}
},
/**
* 百度
*/
BAIDU {
@Override
public String authorize() {
return "https://openapi.baidu.com/oauth/2.0/authorize";
}
@Override
public String accessToken() {
return "https://openapi.baidu.com/oauth/2.0/token";
}
@Override
public String userInfo() {
return "https://openapi.baidu.com/rest/2.0/passport/users/getInfo";
}
@Override
public String revoke() {
return "https://openapi.baidu.com/rest/2.0/passport/auth/revokeAuthorization";
}
@Override
public String refresh() {
return "https://openapi.baidu.com/oauth/2.0/token";
}
},
/**
* csdn
*/
CSDN {
@Override
public String authorize() {
return "https://api.csdn.net/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://api.csdn.net/oauth2/access_token";
}
@Override
public String userInfo() {
return "https://api.csdn.net/user/getinfo";
}
},
/**
* Coding
*/
CODING {
@Override
public String authorize() {
return "https://coding.net/oauth_authorize.html";
}
@Override
public String accessToken() {
return "https://coding.net/api/oauth/access_token";
}
@Override
public String userInfo() {
return "https://coding.net/api/account/current_user";
}
},
/**
* 腾讯云开发者平台(coding升级后就变成腾讯云开发者平台了)
*/
TENCENT_CLOUD {
@Override
public String authorize() {
return "https://dev.tencent.com/oauth_authorize.html";
}
@Override
public String accessToken() {
return "https://dev.tencent.com/api/oauth/access_token";
}
@Override
public String userInfo() {
return "https://dev.tencent.com/api/account/current_user";
}
},
/**
* oschina 开源中国
*/
OSCHINA {
@Override
public String authorize() {
return "https://www.oschina.net/action/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://www.oschina.net/action/openapi/token";
}
@Override
public String userInfo() {
return "https://www.oschina.net/action/openapi/user";
}
},
/**
* 支付宝
*/
ALIPAY {
@Override
public String authorize() {
return "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm";
}
@Override
public String accessToken() {
return "https://openapi.alipay.com/gateway.do";
}
@Override
public String userInfo() {
return "https://openapi.alipay.com/gateway.do";
}
},
/**
* QQ
*/
QQ {
@Override
public String authorize() {
return "https://graph.qq.com/oauth2.0/authorize";
}
@Override
public String accessToken() {
return "https://graph.qq.com/oauth2.0/token";
}
@Override
public String userInfo() {
return "https://graph.qq.com/user/get_user_info";
}
@Override
public String refresh() {
return "https://graph.qq.com/oauth2.0/token";
}
},
/**
* 微信
*/
WECHAT {
@Override
public String authorize() {
return "https://open.weixin.qq.com/connect/qrconnect";
}
@Override
public String accessToken() {
return "https://api.weixin.qq.com/sns/oauth2/access_token";
}
@Override
public String userInfo() {
return "https://api.weixin.qq.com/sns/userinfo";
}
@Override
public String refresh() {
return "https://api.weixin.qq.com/sns/oauth2/refresh_token";
}
},
/**
* 淘宝
*/
TAOBAO {
@Override
public String authorize() {
return "https://oauth.taobao.com/authorize";
}
@Override
public String accessToken() {
return "https://oauth.taobao.com/token";
}
@Override
public String userInfo() {
throw new AuthException(AuthResponseStatus.UNSUPPORTED);
}
},
/**
* Google
*/
GOOGLE {
@Override
public String authorize() {
return "https://accounts.google.com/o/oauth2/v2/auth";
}
@Override
public String accessToken() {
return "https://www.googleapis.com/oauth2/v4/token";
}
@Override
public String userInfo() {
return "https://www.googleapis.com/oauth2/v3/userinfo";
}
},
/**
* Facebook
*/
FACEBOOK {
@Override
public String authorize() {
return "https://www.facebook.com/v3.3/dialog/oauth";
}
@Override
public String accessToken() {
return "https://graph.facebook.com/v3.3/oauth/access_token";
}
@Override
public String userInfo() {
return "https://graph.facebook.com/v3.3/me";
}
},
/**
* 抖音
*/
DOUYIN {
@Override
public String authorize() {
return "https://open.douyin.com/platform/oauth/connect";
}
@Override
public String accessToken() {
return "https://open.douyin.com/oauth/access_token/";
}
@Override
public String userInfo() {
return "https://open.douyin.com/oauth/userinfo/";
}
@Override
public String refresh() {
return "https://open.douyin.com/oauth/refresh_token/";
}
},
/**
* 领英
*/
LINKEDIN {
@Override
public String authorize() {
return "https://www.linkedin.com/oauth/v2/authorization";
}
@Override
public String accessToken() {
return "https://www.linkedin.com/oauth/v2/accessToken";
}
@Override
public String userInfo() {
return "https://api.linkedin.com/v2/me";
}
@Override
public String refresh() {
return "https://www.linkedin.com/oauth/v2/accessToken";
}
},
/**
* 微软
*/
MICROSOFT {
@Override
public String authorize() {
return "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
}
@Override
public String accessToken() {
return "https://login.microsoftonline.com/common/oauth2/v2.0/token";
}
@Override
public String userInfo() {
return "https://graph.microsoft.com/v1.0/me";
}
@Override
public String refresh() {
return "https://login.microsoftonline.com/common/oauth2/v2.0/token";
}
},
/**
* 小米
*/
MI {
@Override
public String authorize() {
return "https://account.xiaomi.com/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://account.xiaomi.com/oauth2/token";
}
@Override
public String userInfo() {
return "https://open.account.xiaomi.com/user/profile";
}
@Override
public String refresh() {
return "https://account.xiaomi.com/oauth2/token";
}
},
/**
* 今日头条
*/
TOUTIAO {
@Override
public String authorize() {
return "https://open.snssdk.com/auth/authorize";
}
@Override
public String accessToken() {
return "https://open.snssdk.com/auth/token";
}
@Override
public String userInfo() {
return "https://open.snssdk.com/data/user_profile";
}
},
/**
* Teambition
*/
TEAMBITION {
@Override
public String authorize() {
return "https://account.teambition.com/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://account.teambition.com/oauth2/access_token";
}
@Override
public String refresh() {
return "https://account.teambition.com/oauth2/refresh_token";
}
@Override
public String userInfo() {
return "https://api.teambition.com/users/me";
}
},
/**
* 人人网
*/
RENREN {
@Override
public String authorize() {
return "https://graph.renren.com/oauth/authorize";
}
@Override
public String accessToken() {
return "https://graph.renren.com/oauth/token";
}
@Override
public String refresh() {
return "https://graph.renren.com/oauth/token";
}
@Override
public String userInfo() {
return "https://api.renren.com/v2/user/get";
}
},
/**
* Pinterest
*/
PINTEREST {
@Override
public String authorize() {
return "https://api.pinterest.com/oauth";
}
@Override
public String accessToken() {
return "https://api.pinterest.com/v1/oauth/token";
}
@Override
public String userInfo() {
return "https://api.pinterest.com/v1/me";
}
},
/**
* Stack Overflow
*/
STACK_OVERFLOW {
@Override
public String authorize() {
return "https://stackoverflow.com/oauth";
}
@Override
public String accessToken() {
return "https://stackoverflow.com/oauth/access_token/json";
}
@Override
public String userInfo() {
return "https://api.stackexchange.com/2.2/me";
}
},
/**
* 华为
*
* @since 1.10.0
*/
HUAWEI {
@Override
public String authorize() {
return "https://oauth-login.cloud.huawei.com/oauth2/v2/authorize";
}
@Override
public String accessToken() {
return "https://oauth-login.cloud.huawei.com/oauth2/v2/token";
}
@Override
public String userInfo() {
return "https://api.vmall.com/rest.php";
}
@Override
public String refresh() {
return "https://oauth-login.cloud.huawei.com/oauth2/v2/token";
}
},
/**
* 企业微信
*
* @since 1.10.0
*/
WECHAT_ENTERPRISE {
@Override
public String authorize() {
return "https://open.work.weixin.qq.com/wwopen/sso/qrConnect";
}
@Override
public String accessToken() {
return "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
}
@Override
public String userInfo() {
return "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo";
}
},
/**
* 酷家乐
*
* @since 1.11.0
*/
KUJIALE {
@Override
public String authorize() {
return "https://oauth.kujiale.com/oauth2/show";
}
@Override
public String accessToken() {
return "https://oauth.kujiale.com/oauth2/auth/token";
}
@Override
public String userInfo() {
return "https://oauth.kujiale.com/oauth2/openapi/user";
}
@Override
public String refresh() {
return "https://oauth.kujiale.com/oauth2/auth/token/refresh";
}
},
/**
* Gitlab
*
* @since 1.11.0
*/
GITLAB {
@Override
public String authorize() {
return "https://gitlab.com/oauth/authorize";
}
@Override
public String accessToken() {
return "https://gitlab.com/oauth/token";
}
@Override
public String userInfo() {
return "https://gitlab.com/api/v4/user";
}
},
/**
* 美团
*
* @since 1.12.0
*/
MEITUAN {
@Override
public String authorize() {
return "https://openapi.waimai.meituan.com/oauth/authorize";
}
@Override
public String accessToken() {
return "https://openapi.waimai.meituan.com/oauth/access_token";
}
@Override
public String userInfo() {
return "https://openapi.waimai.meituan.com/oauth/userinfo";
}
@Override
public String refresh() {
return "https://openapi.waimai.meituan.com/oauth/refresh_token";
}
},
/**
* 饿了么
* <p>
* 注:集成的是正式环境,非沙箱环境
*
* @since 1.12.0
*/
ELEME {
@Override
public String authorize() {
return "https://open-api.shop.ele.me/authorize";
}
@Override
public String accessToken() {
return "https://open-api.shop.ele.me/token";
}
@Override
public String userInfo() {
return "https://open-api.shop.ele.me/api/v1/";
}
@Override
public String refresh() {
return "https://open-api.shop.ele.me/token";
}
}
}
@@ -2,600 +2,54 @@ package me.zhyd.oauth.config;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
/**
* 各api需要的url, 用枚举类分平台类型管理
* OAuth平台的API管理类的统一接口,提供以下接口:
* 1) {@link AuthSource#authorize()}: 获取授权api. 必须实现
* 2) {@link AuthSource#accessToken()}: 获取授权api. 必须实现
* 3) {@link AuthSource#userInfo()}: 获取授权api. 必须实现
* 4) {@link AuthSource#revoke()}: 获取授权api. 非必须实现接口(部分平台不支持)
* 5) {@link AuthSource#refresh()} ()}: 获取授权api. 非必须实现接口(部分平台不支持)
* <p>
* 注:
* ①、如需通过JustAuth扩展实现第三方授权,请参考{@link AuthDefaultSource}自行创建对应的枚举类并实现{@link AuthSource}接口
* ②、如果不是使用的枚举类,那么在授权成功后获取用户信息时,需要单独处理sourcec字段的赋值
* ③、如果扩展了对应枚举类时,在{@link me.zhyd.oauth.request.AuthRequest#login(AuthCallback)}中可以通过{@code xx.toString()}获取对应的source
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @since 1.0
* @version 1.0
* @since 1.12.0
*/
public enum AuthSource {
/**
* Github
*/
GITHUB {
@Override
public String authorize() {
return "https://github.com/login/oauth/authorize";
}
@Override
public String accessToken() {
return "https://github.com/login/oauth/access_token";
}
@Override
public String userInfo() {
return "https://api.github.com/user";
}
},
/**
* 新浪微博
*/
WEIBO {
@Override
public String authorize() {
return "https://api.weibo.com/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://api.weibo.com/oauth2/access_token";
}
@Override
public String userInfo() {
return "https://api.weibo.com/2/users/show.json";
}
},
/**
* gitee
*/
GITEE {
@Override
public String authorize() {
return "https://gitee.com/oauth/authorize";
}
@Override
public String accessToken() {
return "https://gitee.com/oauth/token";
}
@Override
public String userInfo() {
return "https://gitee.com/api/v5/user";
}
},
/**
* 钉钉
*/
DINGTALK {
@Override
public String authorize() {
return "https://oapi.dingtalk.com/connect/qrconnect";
}
@Override
public String accessToken() {
throw new AuthException(AuthResponseStatus.UNSUPPORTED);
}
@Override
public String userInfo() {
return "https://oapi.dingtalk.com/sns/getuserinfo_bycode";
}
},
/**
* 百度
*/
BAIDU {
@Override
public String authorize() {
return "https://openapi.baidu.com/oauth/2.0/authorize";
}
@Override
public String accessToken() {
return "https://openapi.baidu.com/oauth/2.0/token";
}
@Override
public String userInfo() {
return "https://openapi.baidu.com/rest/2.0/passport/users/getInfo";
}
@Override
public String revoke() {
return "https://openapi.baidu.com/rest/2.0/passport/auth/revokeAuthorization";
}
@Override
public String refresh() {
return "https://openapi.baidu.com/oauth/2.0/token";
}
},
/**
* csdn
*/
CSDN {
@Override
public String authorize() {
return "https://api.csdn.net/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://api.csdn.net/oauth2/access_token";
}
@Override
public String userInfo() {
return "https://api.csdn.net/user/getinfo";
}
},
/**
* Coding
*/
CODING {
@Override
public String authorize() {
return "https://coding.net/oauth_authorize.html";
}
@Override
public String accessToken() {
return "https://coding.net/api/oauth/access_token";
}
@Override
public String userInfo() {
return "https://coding.net/api/account/current_user";
}
},
/**
* 腾讯云开发者平台(coding升级后就变成腾讯云开发者平台了)
*/
TENCENT_CLOUD {
@Override
public String authorize() {
return "https://dev.tencent.com/oauth_authorize.html";
}
@Override
public String accessToken() {
return "https://dev.tencent.com/api/oauth/access_token";
}
@Override
public String userInfo() {
return "https://dev.tencent.com/api/account/current_user";
}
},
/**
* oschina 开源中国
*/
OSCHINA {
@Override
public String authorize() {
return "https://www.oschina.net/action/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://www.oschina.net/action/openapi/token";
}
@Override
public String userInfo() {
return "https://www.oschina.net/action/openapi/user";
}
},
/**
* 支付宝
*/
ALIPAY {
@Override
public String authorize() {
return "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm";
}
@Override
public String accessToken() {
return "https://openapi.alipay.com/gateway.do";
}
@Override
public String userInfo() {
return "https://openapi.alipay.com/gateway.do";
}
},
/**
* QQ
*/
QQ {
@Override
public String authorize() {
return "https://graph.qq.com/oauth2.0/authorize";
}
@Override
public String accessToken() {
return "https://graph.qq.com/oauth2.0/token";
}
@Override
public String userInfo() {
return "https://graph.qq.com/user/get_user_info";
}
@Override
public String refresh() {
return "https://graph.qq.com/oauth2.0/token";
}
},
/**
* 微信
*/
WECHAT {
@Override
public String authorize() {
return "https://open.weixin.qq.com/connect/qrconnect";
}
@Override
public String accessToken() {
return "https://api.weixin.qq.com/sns/oauth2/access_token";
}
@Override
public String userInfo() {
return "https://api.weixin.qq.com/sns/userinfo";
}
@Override
public String refresh() {
return "https://api.weixin.qq.com/sns/oauth2/refresh_token";
}
},
/**
* 淘宝
*/
TAOBAO {
@Override
public String authorize() {
return "https://oauth.taobao.com/authorize";
}
@Override
public String accessToken() {
return "https://oauth.taobao.com/token";
}
@Override
public String userInfo() {
throw new AuthException(AuthResponseStatus.UNSUPPORTED);
}
},
/**
* Google
*/
GOOGLE {
@Override
public String authorize() {
return "https://accounts.google.com/o/oauth2/v2/auth";
}
@Override
public String accessToken() {
return "https://www.googleapis.com/oauth2/v4/token";
}
@Override
public String userInfo() {
return "https://www.googleapis.com/oauth2/v3/userinfo";
}
},
/**
* Facebook
*/
FACEBOOK {
@Override
public String authorize() {
return "https://www.facebook.com/v3.3/dialog/oauth";
}
@Override
public String accessToken() {
return "https://graph.facebook.com/v3.3/oauth/access_token";
}
@Override
public String userInfo() {
return "https://graph.facebook.com/v3.3/me";
}
},
/**
* 抖音
*/
DOUYIN {
@Override
public String authorize() {
return "https://open.douyin.com/platform/oauth/connect";
}
@Override
public String accessToken() {
return "https://open.douyin.com/oauth/access_token/";
}
@Override
public String userInfo() {
return "https://open.douyin.com/oauth/userinfo/";
}
@Override
public String refresh() {
return "https://open.douyin.com/oauth/refresh_token/";
}
},
/**
* 领英
*/
LINKEDIN {
@Override
public String authorize() {
return "https://www.linkedin.com/oauth/v2/authorization";
}
@Override
public String accessToken() {
return "https://www.linkedin.com/oauth/v2/accessToken";
}
@Override
public String userInfo() {
return "https://api.linkedin.com/v2/me";
}
@Override
public String refresh() {
return "https://www.linkedin.com/oauth/v2/accessToken";
}
},
/**
* 微软
*/
MICROSOFT {
@Override
public String authorize() {
return "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
}
@Override
public String accessToken() {
return "https://login.microsoftonline.com/common/oauth2/v2.0/token";
}
@Override
public String userInfo() {
return "https://graph.microsoft.com/v1.0/me";
}
@Override
public String refresh() {
return "https://login.microsoftonline.com/common/oauth2/v2.0/token";
}
},
/**
* 小米
*/
MI {
@Override
public String authorize() {
return "https://account.xiaomi.com/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://account.xiaomi.com/oauth2/token";
}
@Override
public String userInfo() {
return "https://open.account.xiaomi.com/user/profile";
}
@Override
public String refresh() {
return "https://account.xiaomi.com/oauth2/token";
}
},
/**
* 今日头条
*/
TOUTIAO {
@Override
public String authorize() {
return "https://open.snssdk.com/auth/authorize";
}
@Override
public String accessToken() {
return "https://open.snssdk.com/auth/token";
}
@Override
public String userInfo() {
return "https://open.snssdk.com/data/user_profile";
}
},
/**
* Teambition
*/
TEAMBITION {
@Override
public String authorize() {
return "https://account.teambition.com/oauth2/authorize";
}
@Override
public String accessToken() {
return "https://account.teambition.com/oauth2/access_token";
}
@Override
public String refresh() {
return "https://account.teambition.com/oauth2/refresh_token";
}
@Override
public String userInfo() {
return "https://api.teambition.com/users/me";
}
},
/**
* 人人网
*/
RENREN {
@Override
public String authorize() {
return "https://graph.renren.com/oauth/authorize";
}
@Override
public String accessToken() {
return "https://graph.renren.com/oauth/token";
}
@Override
public String refresh() {
return "https://graph.renren.com/oauth/token";
}
@Override
public String userInfo() {
return "https://api.renren.com/v2/user/get";
}
},
/**
* Pinterest
*/
PINTEREST {
@Override
public String authorize() {
return "https://api.pinterest.com/oauth";
}
@Override
public String accessToken() {
return "https://api.pinterest.com/v1/oauth/token";
}
@Override
public String userInfo() {
return "https://api.pinterest.com/v1/me";
}
},
/**
* Stack Overflow
*/
STACK_OVERFLOW {
@Override
public String authorize() {
return "https://stackoverflow.com/oauth";
}
@Override
public String accessToken() {
return "https://stackoverflow.com/oauth/access_token/json";
}
@Override
public String userInfo() {
return "https://api.stackexchange.com/2.2/me";
}
},
/**
* 华为
*
* @since 1.10.0
*/
HUAWEI {
@Override
public String authorize() {
return "https://oauth-login.cloud.huawei.com/oauth2/v2/authorize";
}
@Override
public String accessToken() {
return "https://oauth-login.cloud.huawei.com/oauth2/v2/token";
}
@Override
public String userInfo() {
return "https://api.vmall.com/rest.php";
}
@Override
public String refresh() {
return "https://oauth-login.cloud.huawei.com/oauth2/v2/token";
}
},
/**
* 企业微信
*
* @since 1.10.0
*/
WECHAT_ENTERPRISE {
@Override
public String authorize() {
return "https://open.work.weixin.qq.com/wwopen/sso/qrConnect";
}
@Override
public String accessToken() {
return "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
}
@Override
public String userInfo() {
return "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo";
}
};
public interface AuthSource {
/**
* 授权的api
*
* @return url
*/
public abstract String authorize();
String authorize();
/**
* 获取accessToken的api
*
* @return url
*/
public abstract String accessToken();
String accessToken();
/**
* 获取用户信息的api
*
* @return url
*/
public abstract String userInfo();
String userInfo();
/**
* 取消授权的api
*
* @return url
*/
public String revoke() {
default String revoke() {
throw new AuthException(AuthResponseStatus.UNSUPPORTED);
}
@@ -604,8 +58,7 @@ public enum AuthSource {
*
* @return url
*/
public String refresh() {
default String refresh() {
throw new AuthException(AuthResponseStatus.UNSUPPORTED);
}
}
@@ -21,7 +21,7 @@ public enum AuthResponseStatus {
NOT_IMPLEMENTED(5001, "Not Implemented"),
PARAMETER_INCOMPLETE(5002, "Parameter incomplete"),
UNSUPPORTED(5003, "Unsupported operation"),
NO_AUTH_SOURCE(5004, "AuthSource cannot be null"),
NO_AUTH_SOURCE(5004, "AuthDefaultSource cannot be null"),
UNIDENTIFIED_PLATFORM(5005, "Unidentified platform"),
ILLEGAL_REDIRECT_URI(5006, "Illegal redirect uri"),
ILLEGAL_REQUEST(5007, "Illegal request"),
@@ -1,7 +1,6 @@
package me.zhyd.oauth.model;
import lombok.*;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.enums.AuthUserGender;
/**
@@ -61,9 +60,10 @@ public class AuthUser {
/**
* 用户来源
*/
private AuthSource source;
private String source;
/**
* 用户授权的token信息
*/
private AuthToken token;
}
@@ -9,7 +9,7 @@ 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.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -29,14 +29,14 @@ public class AuthAlipayRequest extends AuthDefaultRequest {
private AlipayClient alipayClient;
public AuthAlipayRequest(AuthConfig config) {
super(config, AuthSource.ALIPAY);
this.alipayClient = new DefaultAlipayClient(AuthSource.ALIPAY.accessToken(), config.getClientId(), config.getClientSecret(), "json", "UTF-8", 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, AuthSource.ALIPAY, authStateCache);
this.alipayClient = new DefaultAlipayClient(AuthSource.ALIPAY.accessToken(), config.getClientId(), config.getClientSecret(), "json", "UTF-8", config
super(config, AuthDefaultSource.ALIPAY, authStateCache);
this.alipayClient = new DefaultAlipayClient(AuthDefaultSource.ALIPAY.accessToken(), config.getClientId(), config.getClientSecret(), "json", "UTF-8", config
.getAlipayPublicKey(), "RSA2");
}
@@ -87,7 +87,7 @@ public class AuthAlipayRequest extends AuthDefaultRequest {
.location(location)
.gender(AuthUserGender.getRealGender(response.getGender()))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -25,11 +25,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthBaiduRequest extends AuthDefaultRequest {
public AuthBaiduRequest(AuthConfig config) {
super(config, AuthSource.BAIDU);
super(config, AuthDefaultSource.BAIDU);
}
public AuthBaiduRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.BAIDU, authStateCache);
super(config, AuthDefaultSource.BAIDU, authStateCache);
}
@Override
@@ -52,7 +52,7 @@ public class AuthBaiduRequest extends AuthDefaultRequest {
.remark(object.getString("userdetail"))
.gender(AuthUserGender.getRealGender(object.getString("sex")))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -4,7 +4,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -21,11 +21,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthCodingRequest extends AuthDefaultRequest {
public AuthCodingRequest(AuthConfig config) {
super(config, AuthSource.CODING);
super(config, AuthDefaultSource.CODING);
}
public AuthCodingRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.CODING, authStateCache);
super(config, AuthDefaultSource.CODING, authStateCache);
}
@Override
@@ -59,7 +59,7 @@ public class AuthCodingRequest extends AuthDefaultRequest {
.email(object.getString("email"))
.remark(object.getString("slogan"))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -4,7 +4,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -21,11 +21,11 @@ import me.zhyd.oauth.model.AuthUser;
public class AuthCsdnRequest extends AuthDefaultRequest {
public AuthCsdnRequest(AuthConfig config) {
super(config, AuthSource.CSDN);
super(config, AuthDefaultSource.CSDN);
}
public AuthCsdnRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.CSDN, authStateCache);
super(config, AuthDefaultSource.CSDN, authStateCache);
}
@Override
@@ -48,7 +48,7 @@ public class AuthCsdnRequest extends AuthDefaultRequest {
.blog(object.getString("website"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -6,7 +6,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -24,11 +24,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthDingTalkRequest extends AuthDefaultRequest {
public AuthDingTalkRequest(AuthConfig config) {
super(config, AuthSource.DINGTALK);
super(config, AuthDefaultSource.DINGTALK);
}
public AuthDingTalkRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.DINGTALK, authStateCache);
super(config, AuthDefaultSource.DINGTALK, authStateCache);
}
@Override
@@ -56,7 +56,7 @@ public class AuthDingTalkRequest extends AuthDefaultRequest {
.nickname(object.getString("nick"))
.username(object.getString("nick"))
.gender(AuthUserGender.UNKNOWN)
.source(source)
.source(source.toString())
.token(token)
.build();
}
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -25,11 +25,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthDouyinRequest extends AuthDefaultRequest {
public AuthDouyinRequest(AuthConfig config) {
super(config, AuthSource.DOUYIN);
super(config, AuthDefaultSource.DOUYIN);
}
public AuthDouyinRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.DOUYIN, authStateCache);
super(config, AuthDefaultSource.DOUYIN, authStateCache);
}
@Override
@@ -50,7 +50,7 @@ public class AuthDouyinRequest extends AuthDefaultRequest {
.remark(userInfoObject.getString("description"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -0,0 +1,184 @@
package me.zhyd.oauth.request;
import cn.hutool.core.codec.Base64;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
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.GlobalAuthUtil;
import me.zhyd.oauth.utils.UrlBuilder;
import me.zhyd.oauth.utils.UuidUtils;
import java.util.HashMap;
import java.util.Map;
/**
* 饿了么
* <p>
* 注:集成的是正式环境,非沙箱环境
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @since 1.12.0
*/
public class AuthElemeRequest extends AuthDefaultRequest {
public AuthElemeRequest(AuthConfig config) {
super(config, AuthDefaultSource.ELEME);
}
public AuthElemeRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.ELEME, authStateCache);
}
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpRequest request = HttpRequest.post(source.accessToken())
.form("client_id", config.getClientId())
.form("redirect_uri", config.getRedirectUri())
.form("code", authCallback.getCode())
.form("grant_type", "authorization_code");
// 设置header
this.setHeader(request);
HttpResponse response = request.execute();
JSONObject object = JSONObject.parseObject(response.body());
this.checkResponse(object);
return AuthToken.builder()
.accessToken(object.getString("access_token"))
.refreshToken(object.getString("refresh_token"))
.tokenType(object.getString("token_type"))
.expireIn(object.getIntValue("expires_in"))
.build();
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
Map<String, Object> parameters = new HashMap<>();
// 获取商户账号信息的API接口名称
String action = "eleme.user.getUser";
// 时间戳,单位秒。API服务端允许客户端请求最大时间误差为正负5分钟。
final long timestamp = System.currentTimeMillis();
// 公共参数
Map<String, Object> metasHashMap = new HashMap<>();
metasHashMap.put("app_key", config.getClientId());
metasHashMap.put("timestamp", timestamp);
String signature = GlobalAuthUtil.generateElemeSignature(config.getClientId(), config.getClientSecret(), timestamp, action, authToken.getAccessToken(), parameters);
String requestId = this.getRequestId();
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("nop", "1.0.0");
paramsMap.put("id", requestId);
paramsMap.put("action", action);
paramsMap.put("token", authToken.getAccessToken());
paramsMap.put("metas", metasHashMap);
paramsMap.put("params", parameters);
paramsMap.put("signature", signature);
HttpRequest request = HttpRequest.post(source.userInfo())
.body(JSONObject.toJSONBytes(paramsMap));
// 设置header
this.setHeader(request, "application/json; charset=utf-8", requestId);
HttpResponse response = request.execute();
JSONObject object = JSONObject.parseObject(response.body());
// 校验请求
if (object.containsKey("name")) {
throw new AuthException(object.getString("message"));
}
if (object.containsKey("error") && null != object.get("error")) {
throw new AuthException(object.getJSONObject("error").getString("message"));
}
JSONObject result = object.getJSONObject("result");
return AuthUser.builder()
.uuid(result.getString("userId"))
.username(result.getString("userName"))
.nickname(result.getString("userName"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source.toString())
.build();
}
@Override
public AuthResponse refresh(AuthToken oldToken) {
HttpRequest request = HttpRequest.post(source.refresh())
.form("refresh_token", oldToken.getRefreshToken())
.form("grant_type", "refresh_token");
// 设置header
this.setHeader(request);
HttpResponse response = request.execute();
JSONObject object = JSONObject.parseObject(response.body());
this.checkResponse(object);
return AuthResponse.builder()
.code(AuthResponseStatus.SUCCESS.getCode())
.data(AuthToken.builder()
.accessToken(object.getString("access_token"))
.refreshToken(object.getString("refresh_token"))
.tokenType(object.getString("token_type"))
.expireIn(object.getIntValue("expires_in"))
.build())
.build();
}
@Override
public String authorize(String state) {
return UrlBuilder.fromBaseUrl(super.authorize(state))
.queryParam("scope", "all")
.build();
}
private String getBasic(String appKey, String appSecret) {
StringBuilder sb = new StringBuilder();
String encodeToString = Base64.encode((appKey + ":" + appSecret).getBytes());
sb.append("Basic").append(" ").append(encodeToString);
return sb.toString();
}
private void setHeader(HttpRequest request) {
setHeader(request, "application/x-www-form-urlencoded;charset=UTF-8", getRequestId());
request.header("Authorization", this.getBasic(config.getClientId(), config.getClientSecret()));
}
private void setHeader(HttpRequest request, String contentType, String requestId) {
request.header("Accept", "text/xml,text/javascript,text/html")
.header("Content-Type", contentType)
.header("Accept-Encoding", "gzip")
.header("User-Agent", "eleme-openapi-java-sdk")
.header("x-eleme-requestid", requestId);
}
private String getRequestId() {
return (UuidUtils.getUUID() + "|" + System.currentTimeMillis()).toUpperCase();
}
private void checkResponse(JSONObject object) {
if (object.containsKey("error")) {
throw new AuthException(object.getString("error_description"));
}
}
}
@@ -4,7 +4,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -21,11 +21,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthFacebookRequest extends AuthDefaultRequest {
public AuthFacebookRequest(AuthConfig config) {
super(config, AuthSource.FACEBOOK);
super(config, AuthDefaultSource.FACEBOOK);
}
public AuthFacebookRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.FACEBOOK, authStateCache);
super(config, AuthDefaultSource.FACEBOOK, authStateCache);
}
@Override
@@ -55,7 +55,7 @@ public class AuthFacebookRequest extends AuthDefaultRequest {
.email(object.getString("email"))
.gender(AuthUserGender.getRealGender(object.getString("gender")))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -4,7 +4,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -20,11 +20,11 @@ import me.zhyd.oauth.model.AuthUser;
public class AuthGiteeRequest extends AuthDefaultRequest {
public AuthGiteeRequest(AuthConfig config) {
super(config, AuthSource.GITEE);
super(config, AuthDefaultSource.GITEE);
}
public AuthGiteeRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.GITEE, authStateCache);
super(config, AuthDefaultSource.GITEE, authStateCache);
}
@Override
@@ -59,7 +59,7 @@ public class AuthGiteeRequest extends AuthDefaultRequest {
.remark(object.getString("bio"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -4,7 +4,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -23,20 +23,20 @@ import java.util.Map;
public class AuthGithubRequest extends AuthDefaultRequest {
public AuthGithubRequest(AuthConfig config) {
super(config, AuthSource.GITHUB);
super(config, AuthDefaultSource.GITHUB);
}
public AuthGithubRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.GITHUB, authStateCache);
super(config, AuthDefaultSource.GITHUB, authStateCache);
}
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
Map<String, String> res = GlobalAuthUtil.parseStringToMap(response.body());
if (res.containsKey("error")) {
throw new AuthException(res.get("error") + ":" + res.get("error_description"));
}
this.checkResponse(res.containsKey("error"), res.get("error_description"));
return AuthToken.builder()
.accessToken(res.get("access_token"))
.scope(res.get("scope"))
@@ -48,9 +48,9 @@ public class AuthGithubRequest extends AuthDefaultRequest {
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
if (object.containsKey("error")) {
throw new AuthException(object.getString("error_description"));
}
this.checkResponse(object.containsKey("error"), object.getString("error_description"));
return AuthUser.builder()
.uuid(object.getString("id"))
.username(object.getString("login"))
@@ -63,8 +63,14 @@ public class AuthGithubRequest extends AuthDefaultRequest {
.remark(object.getString("bio"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
private void checkResponse(boolean error, String error_description) {
if (error) {
throw new AuthException(error_description);
}
}
}
@@ -0,0 +1,95 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpResponse;
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.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.UrlBuilder;
/**
* Gitlab登录
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @since 1.11.0
*/
public class AuthGitlabRequest extends AuthDefaultRequest {
public AuthGitlabRequest(AuthConfig config) {
super(config, AuthDefaultSource.GITLAB);
}
public AuthGitlabRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.GITLAB, authStateCache);
}
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
JSONObject object = JSONObject.parseObject(response.body());
this.checkResponse(object);
return AuthToken.builder()
.accessToken(object.getString("access_token"))
.refreshToken(object.getString("refresh_token"))
.idToken(object.getString("id_token"))
.tokenType(object.getString("token_type"))
.scope(object.getString("scope"))
.build();
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = doGetUserInfo(authToken);
JSONObject object = JSONObject.parseObject(response.body());
this.checkResponse(object);
return AuthUser.builder()
.uuid(object.getString("id"))
.username(object.getString("username"))
.nickname(object.getString("name"))
.avatar(object.getString("avatar_url"))
.blog(object.getString("web_url"))
.company(object.getString("organization"))
.location(object.getString("location"))
.email(object.getString("email"))
.remark(object.getString("bio"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source.toString())
.build();
}
private void checkResponse(JSONObject object) {
// oauth/token 验证异常
if (object.containsKey("error")) {
throw new AuthException(object.getString("error_description"));
}
// user 验证异常
if (object.containsKey("message")) {
throw new AuthException(object.getString("message"));
}
}
/**
* 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
*
* @param state state 验证授权流程的参数,可以防止csrf
* @return 返回授权地址
* @since 1.11.0
*/
@Override
public String authorize(String state) {
return UrlBuilder.fromBaseUrl(super.authorize(state))
.queryParam("scope", "read_user+openid+profile+email")
.build();
}
}
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -22,11 +22,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthGoogleRequest extends AuthDefaultRequest {
public AuthGoogleRequest(AuthConfig config) {
super(config, AuthSource.GOOGLE);
super(config, AuthDefaultSource.GOOGLE);
}
public AuthGoogleRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.GOOGLE, authStateCache);
super(config, AuthDefaultSource.GOOGLE, authStateCache);
}
@Override
@@ -60,7 +60,7 @@ public class AuthGoogleRequest extends AuthDefaultRequest {
.email(object.getString("email"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -26,11 +26,11 @@ import static me.zhyd.oauth.enums.AuthResponseStatus.SUCCESS;
public class AuthHuaweiRequest extends AuthDefaultRequest {
public AuthHuaweiRequest(AuthConfig config) {
super(config, AuthSource.HUAWEI);
super(config, AuthDefaultSource.HUAWEI);
}
public AuthHuaweiRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.HUAWEI, authStateCache);
super(config, AuthDefaultSource.HUAWEI, authStateCache);
}
/**
@@ -80,7 +80,7 @@ public class AuthHuaweiRequest extends AuthDefaultRequest {
.gender(gender)
.avatar(object.getString("headPictureURL"))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -0,0 +1,134 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
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.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 shahuang
* @since 1.11.0
*/
public class AuthKujialeRequest extends AuthDefaultRequest {
public AuthKujialeRequest(AuthConfig config) {
super(config, AuthDefaultSource.KUJIALE);
}
public AuthKujialeRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.KUJIALE, authStateCache);
}
/**
* 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
* 默认只向用户请求用户信息授权
*
* @param state state 验证授权流程的参数,可以防止csrf
* @return 返回授权地址
* @since 1.11.0
*/
@Override
public String authorize(String state) {
return authorize(state, "get_user_info");
}
/**
* 请求授权url
*
* @param state state 验证授权流程的参数,可以防止csrf
* @param scopeStr 请求用户授权时向用户显示的可进行授权的列表。如果要填写多个接口名称,请用逗号隔开
* 参考https://open.kujiale.com/open/apps/2/docs?doc_id=95#Step1%EF%BC%9A%E8%8E%B7%E5%8F%96Authorization%20Code参数表内的scope字段
* @return authorize url
*/
public String authorize(String state, String scopeStr) {
UrlBuilder urlBuilder = UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("response_type", "code")
.queryParam("client_id", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
.queryParam("state", getRealState(state));
if (StringUtils.isNotEmpty(scopeStr)) {
urlBuilder.queryParam("scope", scopeStr);
}
return urlBuilder.build();
}
@Override
public AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
return getAuthToken(response);
}
private AuthToken getAuthToken(HttpResponse response) {
JSONObject accessTokenObject = checkResponse(response);
JSONObject resultObject = accessTokenObject.getJSONObject("d");
return AuthToken.builder()
.accessToken(resultObject.getString("accessToken"))
.refreshToken(resultObject.getString("refreshToken"))
.expireIn(resultObject.getIntValue("expiresIn"))
.build();
}
private JSONObject checkResponse(HttpResponse response) {
String accessTokenStr = response.body();
JSONObject accessTokenObject = JSONObject.parseObject(accessTokenStr);
if (!"0".equals(accessTokenObject.getString("c"))) {
throw new AuthException(accessTokenObject.getString("m"));
}
return accessTokenObject;
}
@Override
public AuthUser getUserInfo(AuthToken authToken) {
String openId = this.getOpenId(authToken);
HttpResponse response = HttpRequest.get(UrlBuilder.fromBaseUrl(source.userInfo())
.queryParam("access_token", authToken.getAccessToken())
.queryParam("open_id", openId)
.build()).execute();
JSONObject object = JSONObject.parseObject(response.body());
if (!"0".equals(object.getString("c"))) {
throw new AuthException(object.getString("m"));
}
JSONObject resultObject = object.getJSONObject("d");
return AuthUser.builder()
.username(resultObject.getString("userName"))
.nickname(resultObject.getString("userName"))
.avatar(resultObject.getString("avatar"))
.uuid(resultObject.getString("openId"))
.token(authToken)
.source(source.toString())
.build();
}
/**
* 获取酷家乐的openId,此id在当前client范围内可以唯一识别授权用户
*
* @param authToken 通过{@link AuthKujialeRequest#getAccessToken(AuthCallback)}获取到的{@code authToken}
* @return openId
*/
private String getOpenId(AuthToken authToken) {
HttpResponse response = HttpRequest.get(UrlBuilder.fromBaseUrl("https://oauth.kujiale.com/oauth2/auth/user")
.queryParam("access_token", authToken.getAccessToken())
.build()).execute();
JSONObject accessTokenObject = checkResponse(response);
return accessTokenObject.getString("d");
}
@Override
public AuthResponse refresh(AuthToken authToken) {
HttpResponse response = HttpRequest.post(refreshTokenUrl(authToken.getRefreshToken())).execute();
return AuthResponse.builder().code(AuthResponseStatus.SUCCESS.getCode()).data(getAuthToken(response)).build();
}
}
@@ -7,7 +7,7 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -28,11 +28,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthLinkedinRequest extends AuthDefaultRequest {
public AuthLinkedinRequest(AuthConfig config) {
super(config, AuthSource.LINKEDIN);
super(config, AuthDefaultSource.LINKEDIN);
}
public AuthLinkedinRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.LINKEDIN, authStateCache);
super(config, AuthDefaultSource.LINKEDIN, authStateCache);
}
@Override
@@ -67,7 +67,7 @@ public class AuthLinkedinRequest extends AuthDefaultRequest {
.email(email)
.token(authToken)
.gender(AuthUserGender.UNKNOWN)
.source(AuthSource.LINKEDIN)
.source(source.toString())
.build();
}
@@ -0,0 +1,114 @@
package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
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.UrlBuilder;
/**
* 美团登录
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @since 1.12.0
*/
public class AuthMeituanRequest extends AuthDefaultRequest {
public AuthMeituanRequest(AuthConfig config) {
super(config, AuthDefaultSource.MEITUAN);
}
public AuthMeituanRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthDefaultSource.MEITUAN, authStateCache);
}
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
HttpResponse response = HttpRequest.post(source.accessToken())
.form("app_id", config.getClientId())
.form("secret", config.getClientSecret())
.form("code", authCallback.getCode())
.form("grant_type", "authorization_code")
.execute();
JSONObject object = JSONObject.parseObject(response.body());
this.checkResponse(object);
return AuthToken.builder()
.accessToken(object.getString("access_token"))
.refreshToken(object.getString("refresh_token"))
.expireIn(object.getIntValue("expires_in"))
.build();
}
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
HttpResponse response = HttpRequest.post(source.userInfo())
.form("app_id", config.getClientId())
.form("secret", config.getClientSecret())
.form("access_token", authToken.getAccessToken())
.execute();
JSONObject object = JSONObject.parseObject(response.body());
this.checkResponse(object);
return AuthUser.builder()
.uuid(object.getString("openid"))
.username(object.getString("nickname"))
.nickname(object.getString("nickname"))
.avatar(object.getString("avatar"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source.toString())
.build();
}
@Override
public AuthResponse refresh(AuthToken oldToken) {
HttpResponse response = HttpRequest.post(source.refresh())
.form("app_id", config.getClientId())
.form("secret", config.getClientSecret())
.form("refresh_token", oldToken.getRefreshToken())
.form("grant_type", "refresh_token")
.execute();
JSONObject object = JSONObject.parseObject(response.body());
this.checkResponse(object);
return AuthResponse.builder()
.code(AuthResponseStatus.SUCCESS.getCode())
.data(AuthToken.builder()
.accessToken(object.getString("access_token"))
.refreshToken(object.getString("refresh_token"))
.expireIn(object.getIntValue("expires_in"))
.build())
.build();
}
private void checkResponse(JSONObject object) {
if (object.containsKey("error_code")) {
throw new AuthException(object.getString("erroe_msg"));
}
}
@Override
public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("response_type", "code")
.queryParam("app_id", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
.queryParam("state", getRealState(state))
.queryParam("scope", "")
.build();
}
}
@@ -6,7 +6,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -29,11 +29,11 @@ public class AuthMiRequest extends AuthDefaultRequest {
private static final String PREFIX = "&&&START&&&";
public AuthMiRequest(AuthConfig config) {
super(config, AuthSource.MI);
super(config, AuthDefaultSource.MI);
}
public AuthMiRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.MI, authStateCache);
super(config, AuthDefaultSource.MI, authStateCache);
}
@Override
@@ -82,7 +82,7 @@ public class AuthMiRequest extends AuthDefaultRequest {
.email(user.getString("mail"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
// 获取用户邮箱手机号等信息
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -25,11 +25,11 @@ import static me.zhyd.oauth.utils.GlobalAuthUtil.parseQueryToMap;
*/
public class AuthMicrosoftRequest extends AuthDefaultRequest {
public AuthMicrosoftRequest(AuthConfig config) {
super(config, AuthSource.MICROSOFT);
super(config, AuthDefaultSource.MICROSOFT);
}
public AuthMicrosoftRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.MICROSOFT, authStateCache);
super(config, AuthDefaultSource.MICROSOFT, authStateCache);
}
@Override
@@ -91,7 +91,7 @@ public class AuthMicrosoftRequest extends AuthDefaultRequest {
.email(object.getString("mail"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -4,7 +4,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -21,11 +21,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthOschinaRequest extends AuthDefaultRequest {
public AuthOschinaRequest(AuthConfig config) {
super(config, AuthSource.OSCHINA);
super(config, AuthDefaultSource.OSCHINA);
}
public AuthOschinaRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.OSCHINA, authStateCache);
super(config, AuthDefaultSource.OSCHINA, authStateCache);
}
@Override
@@ -56,7 +56,7 @@ public class AuthOschinaRequest extends AuthDefaultRequest {
.gender(AuthUserGender.getRealGender(object.getString("gender")))
.email(object.getString("email"))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -14,7 +14,7 @@ import me.zhyd.oauth.utils.UrlBuilder;
import java.util.Objects;
import static me.zhyd.oauth.config.AuthSource.PINTEREST;
import static me.zhyd.oauth.config.AuthDefaultSource.PINTEREST;
/**
* Pinterest登录
@@ -60,7 +60,7 @@ public class AuthPinterestRequest extends AuthDefaultRequest {
.gender(AuthUserGender.UNKNOWN)
.remark(userObj.getString("bio"))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -6,7 +6,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -29,11 +29,11 @@ import java.util.Map;
*/
public class AuthQqRequest extends AuthDefaultRequest {
public AuthQqRequest(AuthConfig config) {
super(config, AuthSource.QQ);
super(config, AuthDefaultSource.QQ);
}
public AuthQqRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.QQ, authStateCache);
super(config, AuthDefaultSource.QQ, authStateCache);
}
@Override
@@ -70,13 +70,13 @@ public class AuthQqRequest extends AuthDefaultRequest {
.uuid(openId)
.gender(AuthUserGender.getRealGender(object.getString("gender")))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
/**
* 获取QQ用户的OpenId支持自定义是否启用查询unionid的功能如果启用查询unionid的功能
* 那就需要调用者先通过邮件申请unionid功能参考链接 {@see http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D}
* 那就需要开发者先通过邮件申请unionid功能参考链接 {@see http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D}
*
* @param authToken 通过{@link AuthQqRequest#getAccessToken(AuthCallback)}获取到的{@code authToken}
* @return openId
@@ -16,7 +16,7 @@ import me.zhyd.oauth.utils.UrlBuilder;
import java.util.Objects;
import static me.zhyd.oauth.config.AuthSource.RENREN;
import static me.zhyd.oauth.config.AuthDefaultSource.RENREN;
import static me.zhyd.oauth.enums.AuthResponseStatus.SUCCESS;
/**
@@ -52,7 +52,7 @@ public class AuthRenrenRequest extends AuthDefaultRequest {
.company(getCompany(userObj))
.gender(getGender(userObj))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -12,7 +12,7 @@ import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder;
import static me.zhyd.oauth.config.AuthSource.STACK_OVERFLOW;
import static me.zhyd.oauth.config.AuthDefaultSource.STACK_OVERFLOW;
import static me.zhyd.oauth.utils.GlobalAuthUtil.parseQueryToMap;
/**
@@ -67,7 +67,7 @@ public class AuthStackOverflowRequest extends AuthDefaultRequest {
.blog(userObj.getString("website_url"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -4,7 +4,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -22,11 +22,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthTaobaoRequest extends AuthDefaultRequest {
public AuthTaobaoRequest(AuthConfig config) {
super(config, AuthSource.TAOBAO);
super(config, AuthDefaultSource.TAOBAO);
}
public AuthTaobaoRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.TAOBAO, authStateCache);
super(config, AuthDefaultSource.TAOBAO, authStateCache);
}
@Override
@@ -54,7 +54,7 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
.nickname(nick)
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -23,11 +23,11 @@ import me.zhyd.oauth.model.AuthUser;
public class AuthTeambitionRequest extends AuthDefaultRequest {
public AuthTeambitionRequest(AuthConfig config) {
super(config, AuthSource.TEAMBITION);
super(config, AuthDefaultSource.TEAMBITION);
}
public AuthTeambitionRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.TEAMBITION, authStateCache);
super(config, AuthDefaultSource.TEAMBITION, authStateCache);
}
/**
@@ -75,7 +75,7 @@ public class AuthTeambitionRequest extends AuthDefaultRequest {
.email(object.getString("email"))
.gender(AuthUserGender.UNKNOWN)
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -4,7 +4,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -21,11 +21,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthTencentCloudRequest extends AuthDefaultRequest {
public AuthTencentCloudRequest(AuthConfig config) {
super(config, AuthSource.TENCENT_CLOUD);
super(config, AuthDefaultSource.TENCENT_CLOUD);
}
public AuthTencentCloudRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.TENCENT_CLOUD, authStateCache);
super(config, AuthDefaultSource.TENCENT_CLOUD, authStateCache);
}
@Override
@@ -59,7 +59,7 @@ public class AuthTencentCloudRequest extends AuthDefaultRequest {
.email(object.getString("email"))
.remark(object.getString("slogan"))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -4,7 +4,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthToutiaoErrorCode;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -22,11 +22,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthToutiaoRequest extends AuthDefaultRequest {
public AuthToutiaoRequest(AuthConfig config) {
super(config, AuthSource.TOUTIAO);
super(config, AuthDefaultSource.TOUTIAO);
}
public AuthToutiaoRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.TOUTIAO, authStateCache);
super(config, AuthDefaultSource.TOUTIAO, authStateCache);
}
@Override
@@ -64,7 +64,7 @@ public class AuthToutiaoRequest extends AuthDefaultRequest {
.remark(user.getString("description"))
.gender(AuthUserGender.getRealGender(user.getString("gender")))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -24,11 +24,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
*/
public class AuthWeChatEnterpriseRequest extends AuthDefaultRequest {
public AuthWeChatEnterpriseRequest(AuthConfig config) {
super(config, AuthSource.WECHAT_ENTERPRISE);
super(config, AuthDefaultSource.WECHAT_ENTERPRISE);
}
public AuthWeChatEnterpriseRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.WECHAT_ENTERPRISE, authStateCache);
super(config, AuthDefaultSource.WECHAT_ENTERPRISE, authStateCache);
}
/**
@@ -74,7 +74,7 @@ public class AuthWeChatEnterpriseRequest extends AuthDefaultRequest {
.uuid(userId)
.gender(AuthUserGender.getRealGender(gender))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
@@ -23,11 +23,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
*/
public class AuthWeChatRequest extends AuthDefaultRequest {
public AuthWeChatRequest(AuthConfig config) {
super(config, AuthSource.WECHAT);
super(config, AuthDefaultSource.WECHAT);
}
public AuthWeChatRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.WECHAT, authStateCache);
super(config, AuthDefaultSource.WECHAT, authStateCache);
}
/**
@@ -64,7 +64,7 @@ public class AuthWeChatRequest extends AuthDefaultRequest {
.uuid(openId)
.gender(AuthUserGender.getRealGender(object.getString("sex")))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -25,11 +25,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthWeiboRequest extends AuthDefaultRequest {
public AuthWeiboRequest(AuthConfig config) {
super(config, AuthSource.WEIBO);
super(config, AuthDefaultSource.WEIBO);
}
public AuthWeiboRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.WEIBO, authStateCache);
super(config, AuthDefaultSource.WEIBO, authStateCache);
}
@Override
@@ -73,7 +73,7 @@ public class AuthWeiboRequest extends AuthDefaultRequest {
.remark(object.getString("description"))
.gender(AuthUserGender.getRealGender(object.getString("gender")))
.token(authToken)
.source(source)
.source(source.toString())
.build();
}
@@ -1,6 +1,7 @@
package me.zhyd.oauth.utils;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.exception.AuthException;
@@ -24,13 +25,13 @@ public class AuthChecker {
*/
public static boolean isSupportedAuth(AuthConfig config, AuthSource source) {
boolean isSupported = StringUtils.isNotEmpty(config.getClientId()) && StringUtils.isNotEmpty(config.getClientSecret()) && StringUtils.isNotEmpty(config.getRedirectUri());
if (isSupported && AuthSource.ALIPAY == source) {
if (isSupported && AuthDefaultSource.ALIPAY == source) {
isSupported = StringUtils.isNotEmpty(config.getAlipayPublicKey());
}
if (isSupported && AuthSource.STACK_OVERFLOW == source) {
if (isSupported && AuthDefaultSource.STACK_OVERFLOW == source) {
isSupported = StringUtils.isNotEmpty(config.getStackOverflowKey());
}
if (isSupported && AuthSource.WECHAT_ENTERPRISE == source){
if (isSupported && AuthDefaultSource.WECHAT_ENTERPRISE == source){
isSupported = StringUtils.isNotEmpty(config.getAgentId());
}
return isSupported;
@@ -49,11 +50,11 @@ public class AuthChecker {
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI);
}
// facebook的回调地址必须为https的链接
if (AuthSource.FACEBOOK == source && !GlobalAuthUtil.isHttpsProtocol(redirectUri)) {
if (AuthDefaultSource.FACEBOOK == source && !GlobalAuthUtil.isHttpsProtocol(redirectUri)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI);
}
// 支付宝在创建回调地址时不允许使用localhost或者127.0.0.1
if (AuthSource.ALIPAY == source && GlobalAuthUtil.isLocalHost(redirectUri)) {
if (AuthDefaultSource.ALIPAY == source && GlobalAuthUtil.isLocalHost(redirectUri)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI);
}
}
@@ -69,9 +70,9 @@ public class AuthChecker {
*/
public static void checkCode(AuthSource source, AuthCallback callback) {
String code = callback.getCode();
if (source == AuthSource.ALIPAY) {
if (source == AuthDefaultSource.ALIPAY) {
code = callback.getAuth_code();
} else if (source == AuthSource.HUAWEI) {
} else if (source == AuthDefaultSource.HUAWEI) {
code = callback.getAuthorization_code();
}
if (StringUtils.isEmpty(code)) {
@@ -4,6 +4,7 @@ import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import me.zhyd.oauth.exception.AuthException;
import javax.crypto.Mac;
@@ -14,6 +15,7 @@ import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
@@ -27,11 +29,25 @@ public class GlobalAuthUtil {
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
private static final String ALGORITHM = "HmacSHA256";
/**
* 生成钉钉请求的Signature
*
* @param secretKey 平台应用的授权密钥
* @param timestamp 时间戳
* @return Signature
*/
public static String generateDingTalkSignature(String secretKey, String timestamp) {
byte[] signData = sign(secretKey.getBytes(DEFAULT_ENCODING), timestamp.getBytes(DEFAULT_ENCODING));
return urlEncode(new String(Base64.encode(signData, false)));
}
/**
* 签名
*
* @param key key
* @param data data
* @return byte[]
*/
private static byte[] sign(byte[] key, byte[] data) {
try {
Mac mac = Mac.getInstance(ALGORITHM);
@@ -44,11 +60,16 @@ public class GlobalAuthUtil {
}
}
/**
* 编码
*
* @param value str
* @return encode str
*/
public static String urlEncode(String value) {
if (value == null) {
return "";
}
try {
String encoded = URLEncoder.encode(value, GlobalAuthUtil.DEFAULT_ENCODING.displayName());
return encoded.replace("+", "%20").replace("*", "%2A").replace("~", "%7E").replace("/", "%2F");
@@ -57,6 +78,13 @@ public class GlobalAuthUtil {
}
}
/**
* 解码
*
* @param value str
* @return decode str
*/
public static String urlDecode(String value) {
if (value == null) {
return "";
@@ -68,6 +96,12 @@ public class GlobalAuthUtil {
}
}
/**
* string字符串转mapstr格式为 {@code xxx=xxx&xxx=xxx}
*
* @param accessTokenStr 待转换的字符串
* @return map
*/
public static Map<String, String> parseStringToMap(String accessTokenStr) {
Map<String, String> res = new HashMap<>();
if (accessTokenStr.contains("&")) {
@@ -82,7 +116,13 @@ public class GlobalAuthUtil {
return res;
}
/**
* map转字符串转换后的字符串格式为 {@code xxx=xxx&xxx=xxx}
*
* @param params 待转换的map
* @param encode 是否转码
* @return str
*/
public static String parseMapToString(Map<String, Object> params, boolean encode) {
List<String> paramList = new ArrayList<>();
params.forEach((k, v) -> {
@@ -95,13 +135,25 @@ public class GlobalAuthUtil {
});
return CollUtil.join(paramList, "&");
}
/**
* 将url的参数列表转换成map
*
* @param url 待转换的url
* @return map
*/
public static Map<String, Object> parseQueryToMap(String url) {
Map<String, Object> paramMap = new HashMap<>();
HttpUtil.decodeParamMap(url, "UTF-8").forEach(paramMap::put);
return paramMap;
}
/**
* 是否为http协议
*
* @param url 待验证的url
* @return true: http协议, false: 非http协议
*/
public static boolean isHttpProtocol(String url) {
if (StringUtils.isEmpty(url)) {
return false;
@@ -109,6 +161,12 @@ public class GlobalAuthUtil {
return url.startsWith("http://");
}
/**
* 是否为https协议
*
* @param url 待验证的url
* @return true: https协议, false: 非https协议
*/
public static boolean isHttpsProtocol(String url) {
if (StringUtils.isEmpty(url)) {
return false;
@@ -116,8 +174,68 @@ public class GlobalAuthUtil {
return url.startsWith("https://");
}
/**
* 是否为本地主机域名
*
* @param url 待验证的url
* @return true: 本地主机域名, false: 非本地主机域名
*/
public static boolean isLocalHost(String url) {
return StringUtils.isEmpty(url) || url.contains("127.0.0.1") || url.contains("localhost");
}
/**
* 生成饿了么请求的Signature
* <p>
* 代码copy并修改自https://coding.net/u/napos_openapi/p/eleme-openapi-java-sdk/git/blob/master/src/main/java/eleme/openapi/sdk/utils/SignatureUtil.java
*
* @param appKey 平台应用的授权key
* @param secret 平台应用的授权密钥
* @param timestamp 时间戳单位秒API服务端允许客户端请求最大时间误差为正负5分钟
* @param action 饿了么请求的api方法
* @param token 用户授权的token
* @param parameters 加密参数
* @return Signature
*/
public static String generateElemeSignature(String appKey, String secret, long timestamp, String action, String token, Map<String, Object> parameters) {
final Map<String, Object> sorted = new TreeMap<>();
for (Map.Entry<String, Object> entry : parameters.entrySet()) {
sorted.put(entry.getKey(), entry.getValue());
}
sorted.put("app_key", appKey);
sorted.put("timestamp", timestamp);
StringBuffer string = new StringBuffer();
for (Map.Entry<String, Object> entry : sorted.entrySet()) {
string.append(entry.getKey()).append("=").append(JSON.toJSONString(entry.getValue()));
}
String splice = String.format("%s%s%s%s", action, token, string, secret);
String calculatedSignature = md5(splice);
return calculatedSignature.toUpperCase();
}
/**
* MD5加密饿了么请求的Signature
* <p>
* 代码copy并修改自https://coding.net/u/napos_openapi/p/eleme-openapi-java-sdk/git/blob/master/src/main/java/eleme/openapi/sdk/utils/SignatureUtil.java
*
* @param str 饿了么请求的Signature
* @return md5 str
*/
private static String md5(String str) {
MessageDigest md = null;
StringBuilder buffer = null;
try {
md = MessageDigest.getInstance("MD5");
md.update(str.getBytes(StandardCharsets.UTF_8));
byte[] byteData = md.digest();
buffer = new StringBuilder();
for (byte byteDatum : byteData) {
buffer.append(Integer.toString((byteDatum & 0xff) + 0x100, 16).substring(1));
}
} catch (Exception ignored) {
}
return null == buffer ? "" : buffer.toString();
}
}
@@ -0,0 +1,63 @@
package me.zhyd.oauth.config;
/**
* 测试自定义实现{@link AuthSource}接口后的枚举类
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0
* @since 1.12.0
*/
public enum AuthExtendSource implements AuthSource {
OTHER {
/**
* 授权的api
*
* @return url
*/
@Override
public String authorize() {
return "http://authorize";
}
/**
* 获取accessToken的api
*
* @return url
*/
@Override
public String accessToken() {
return "http://accessToken";
}
/**
* 获取用户信息的api
*
* @return url
*/
@Override
public String userInfo() {
return null;
}
/**
* 取消授权的api
*
* @return url
*/
@Override
public String revoke() {
return null;
}
/**
* 刷新授权的api
*
* @return url
*/
@Override
public String refresh() {
return null;
}
}
}
@@ -1,6 +1,9 @@
package me.zhyd.oauth.model;
import com.alibaba.fastjson.JSON;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.config.AuthExtendSource;
import me.zhyd.oauth.config.AuthSource;
import org.junit.Assert;
import org.junit.Test;
@@ -28,4 +31,25 @@ public class AuthUserTest {
Assert.assertEquals(deserializeUser.getNickname(), "test");
}
@Test
public void source() {
AuthSource source = AuthDefaultSource.HUAWEI;
AuthUser user = AuthUser.builder()
.source(source.toString())
.build();
Assert.assertEquals(user.getSource(), "HUAWEI");
source = AuthExtendSource.OTHER;
user = AuthUser.builder()
.source(source.toString())
.build();
Assert.assertEquals(user.getSource(), "OTHER");
source = AuthDefaultSource.HUAWEI;
Assert.assertEquals(source, AuthDefaultSource.HUAWEI);
source = AuthExtendSource.OTHER;
Assert.assertEquals(source, AuthExtendSource.OTHER);
}
}
@@ -0,0 +1,104 @@
package me.zhyd.oauth.request;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthExtendSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
/**
* 测试用自定义扩展的第三方request
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0
* @since 1.12.0
*/
public class AuthExtendRequest extends AuthDefaultRequest {
public AuthExtendRequest(AuthConfig config) {
super(config, AuthExtendSource.OTHER);
}
public AuthExtendRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthExtendSource.OTHER, authStateCache);
}
/**
* 获取access token
*
* @param authCallback 授权成功后的回调参数
* @return token
* @see AuthDefaultRequest#authorize()
* @see AuthDefaultRequest#authorize(String)
*/
@Override
protected AuthToken getAccessToken(AuthCallback authCallback) {
return AuthToken.builder()
.openId("openId")
.expireIn(1000)
.idToken("idToken")
.scope("scope")
.refreshToken("refreshToken")
.accessToken("accessToken")
.code("code")
.build();
}
/**
* 使用token换取用户信息
*
* @param authToken token信息
* @return 用户信息
* @see AuthDefaultRequest#getAccessToken(AuthCallback)
*/
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
return AuthUser.builder()
.username("test")
.nickname("test")
.gender(AuthUserGender.MALE)
.token(authToken)
.source(this.source.toString())
.build();
}
/**
* 撤销授权
*
* @param authToken 登录成功后返回的Token信息
* @return AuthResponse
*/
@Override
public AuthResponse revoke(AuthToken authToken) {
return AuthResponse.builder()
.code(AuthResponseStatus.SUCCESS.getCode())
.msg(AuthResponseStatus.SUCCESS.getMsg())
.build();
}
/**
* 刷新access token 续期
*
* @param authToken 登录成功后返回的Token信息
* @return AuthResponse
*/
@Override
public AuthResponse refresh(AuthToken authToken) {
return AuthResponse.builder()
.code(AuthResponseStatus.SUCCESS.getCode())
.data(AuthToken.builder()
.openId("openId")
.expireIn(1000)
.idToken("idToken")
.scope("scope")
.refreshToken("refreshToken")
.accessToken("accessToken")
.code("code")
.build())
.build();
}
}
@@ -0,0 +1,81 @@
package me.zhyd.oauth.request;
import com.alibaba.fastjson.JSON;
import me.zhyd.oauth.config.AuthConfig;
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.AuthStateUtils;
import org.junit.Assert;
import org.junit.Test;
/**
* 自定义扩展的第三方request的测试类用于演示具体的用法
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0
* @since 1.12.0
*/
public class AuthExtendRequestTest {
@Test
public void authorize() {
AuthRequest request = new AuthExtendRequest(AuthConfig.builder()
.clientId("clientId")
.clientSecret("clientSecret")
.redirectUri("http://redirectUri")
.build());
String authorize = request.authorize(AuthStateUtils.createState());
System.out.println(authorize);
Assert.assertNotNull(authorize);
}
@Test
public void login() {
AuthRequest request = new AuthExtendRequest(AuthConfig.builder()
.clientId("clientId")
.clientSecret("clientSecret")
.redirectUri("http://redirectUri")
.build());
String state = AuthStateUtils.createState();
request.authorize(state);
AuthCallback callback = new AuthCallback();
callback.setCode("code");
callback.setState(state);
AuthResponse response = request.login(callback);
Assert.assertNotNull(response);
AuthUser user = (AuthUser) response.getData();
Assert.assertNotNull(user);
System.out.println(JSON.toJSONString(user));
}
@Test
public void revoke() {
AuthRequest request = new AuthExtendRequest(AuthConfig.builder()
.clientId("clientId")
.clientSecret("clientSecret")
.redirectUri("http://redirectUri")
.build());
AuthResponse response = request.revoke(AuthToken.builder().build());
Assert.assertNotNull(response);
System.out.println(JSON.toJSONString(response));
}
@Test
public void refresh() {
AuthRequest request = new AuthExtendRequest(AuthConfig.builder()
.clientId("clientId")
.clientSecret("clientSecret")
.redirectUri("http://redirectUri")
.build());
AuthResponse response = request.refresh(AuthToken.builder().build());
Assert.assertNotNull(response);
System.out.println(JSON.toJSONString(response.getData()));
}
}
@@ -1,4 +1,4 @@
package me.zhyd.oauth;
package me.zhyd.oauth.request;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback;
@@ -20,7 +20,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@@ -34,7 +34,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@@ -48,7 +48,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@@ -62,7 +62,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@@ -76,7 +76,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@@ -90,7 +90,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@@ -104,7 +104,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@@ -118,7 +118,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@@ -133,7 +133,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -147,7 +147,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -161,7 +161,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -175,7 +175,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -189,7 +189,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -203,7 +203,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -217,7 +217,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -231,7 +231,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -245,7 +245,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -259,7 +259,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -273,7 +273,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -287,7 +287,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -302,7 +302,7 @@ public class AuthRequestTest {
.build());
// 返回授权页面可自行跳转
authRequest.authorize("state");
// 授权登录后会返回codeauth_code仅限支付宝state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// 授权登录后会返回codeauth_code仅限支付宝authorization_code仅限华为state1.8.0版本后可以用AuthCallback类作为回调接口的入参
// JustAuth默认保存state的时效为3分钟3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@@ -1,7 +1,7 @@
package me.zhyd.oauth.utils;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.request.AuthWeChatRequest;
import org.junit.Assert;
import org.junit.Test;
@@ -22,7 +22,7 @@ public class UrlBuilderTest {
.clientSecret("secret-110110110")
.redirectUri("https://xkcoding.com")
.build();
String build = UrlBuilder.fromBaseUrl(AuthSource.WECHAT.authorize())
String build = UrlBuilder.fromBaseUrl(AuthDefaultSource.WECHAT.authorize())
.queryParam("appid", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
.queryParam("response_type", "code")