1
0
mirror of synced 2026-05-22 13:43:20 +00:00

Compare commits

...

18 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
59 changed files with 1892 additions and 823 deletions
+5 -5
View File
@@ -1,15 +1,15 @@
[ ] 是否为解决Issue
- [ ] 是否为解决Issue
### 您做了哪些更新?
#### 新增
- 新增
#### 修改
- 修改
#### 修复
- 修复
#### 其他
- 其他
### 是否做了充分测试?
+23 -6
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.11.0-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.11.0-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>
@@ -66,6 +66,8 @@
<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>
@@ -113,12 +115,13 @@ authRequest.login(callback);
**Examples**
- [Springboot Example](https://gitee.com/yadong.zhang/JustAuth-demo)
- [jFinal Example](https://github.com/xkcoding/jfinal-justauth-demo)
- [ActFramework Example](https://github.com/xkcoding/act-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
- [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 |
@@ -150,6 +153,8 @@ authRequest.login(callback);
| <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) | 无 |
@@ -165,6 +170,18 @@ authRequest.login(callback);
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)
+27 -18
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.11.0-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.11.0-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>
@@ -66,6 +66,8 @@
<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>
@@ -93,7 +95,7 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.11.0</version>
<version>1.12.0</version>
</dependency>
```
- 调用api
@@ -113,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)
具体的例子可以参考:
@@ -160,6 +158,8 @@ authRequest.login(callback);
| <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登录只能针对少部分用户使用了_
@@ -179,15 +179,25 @@ _请知悉:经咨询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
@@ -206,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>
- 千年等一回,我只为等你...
+11 -4
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.11.0-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.11.0-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>
@@ -87,9 +87,11 @@ 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/csdn.png" width="20"> | [AuthCsdnRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java) | 无 |
| <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) | 无 |
## 快速开始
@@ -153,6 +155,11 @@ 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
## 捐赠
+3 -2
View File
@@ -1,13 +1,14 @@
- [入门和使用](README.md)
- [贡献者名单](contributors.md)
- 快速开始
- [名词解释](explain.md)
- [OAuth流程](oauth.md)
- [如何使用](how-to-use.md)
- [获取授权链接](authorize.md)
- [登录](login.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: 如有遗漏,请告知
+4 -4
View File
@@ -2,7 +2,7 @@
## 本文相关名词
- `调用者` 指使用`JustAuth`的开发者
- `开发者` 指使用`JustAuth`的开发者
- `第三方` 指开发者对接的第三方网站,比如:QQ平台、微信平台、微博平台
- `用户` 指最终服务的真实用户
@@ -12,9 +12,9 @@
- `clientId` 客户端身份标识符(应用id),一般在申请完Oauth应用后,由**第三方平台颁发**,唯一
- `clientSecret` 客户端密钥,一般在申请完Oauth应用后,由**第三方平台颁发**
- `redirectUri` **调用者项目中的有效api地址**。用户在确认第三方平台授权(登录)后,第三方平台会重定向到该地址,并携带code等参数
- `state` 用来保持授权会话流程完整性,防止CSRF攻击的安全的随机的参数,由**调用者生成**
- `alipayPublicKey` 支付宝公钥。当选择支付宝登录时,必传该值,由**调用者生成**
- `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
+115
View File
@@ -1,13 +1,18 @@
# 如何使用
在前面有介绍到,JustAuth的特点之一就是**简**,极简主义,不给使用者造成不必要的障碍。
既然牛皮吹下了, 那么如何才能用JustAuth实现第三方登录呢?
## 使用步骤
使用JustAuth总共分三步(**这三步也适合于JustAuth支持的任何一个平台**):
1. 申请注册第三方平台的开发者账号
2. 创建第三方平台的应用,获取配置信息(`accessKey`, `secretKey`, `redirectUri`)
3. 使用该工具实现授权登陆
## 使用方式
- 引入依赖
```xml
@@ -30,4 +35,114 @@ 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());
}
```
-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>
+7
View File
@@ -1,3 +1,10 @@
## 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
+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`进行修改,不建议修改太大。
+2 -2
View File
@@ -6,7 +6,7 @@
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.11.0</version>
<version>1.12.0</version>
<name>JustAuth</name>
<url>https://gitee.com/yadong.zhang/JustAuth</url>
@@ -62,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>
@@ -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,649 +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";
}
},
/**
* 酷家乐
*
* @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";
}
};
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);
}
@@ -653,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,7 +60,7 @@ public class AuthUser {
/**
* 用户来源
*/
private AuthSource source;
private String source;
/**
* 用户授权的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,11 +23,11 @@ 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
@@ -63,7 +63,7 @@ public class AuthGithubRequest 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;
@@ -21,11 +21,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthGitlabRequest extends AuthDefaultRequest {
public AuthGitlabRequest(AuthConfig config) {
super(config, AuthSource.GITLAB);
super(config, AuthDefaultSource.GITLAB);
}
public AuthGitlabRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.GITLAB, authStateCache);
super(config, AuthDefaultSource.GITLAB, authStateCache);
}
@Override
@@ -63,7 +63,7 @@ public class AuthGitlabRequest extends AuthDefaultRequest {
.remark(object.getString("bio"))
.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;
@@ -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();
}
@@ -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.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
@@ -24,11 +24,11 @@ import me.zhyd.oauth.utils.UrlBuilder;
public class AuthKujialeRequest extends AuthDefaultRequest {
public AuthKujialeRequest(AuthConfig config) {
super(config, AuthSource.KUJIALE);
super(config, AuthDefaultSource.KUJIALE);
}
public AuthKujialeRequest(AuthConfig config, AuthStateCache authStateCache) {
super(config, AuthSource.KUJIALE, authStateCache);
super(config, AuthDefaultSource.KUJIALE, authStateCache);
}
/**
@@ -108,7 +108,7 @@ public class AuthKujialeRequest extends AuthDefaultRequest {
.avatar(resultObject.getString("avatar"))
.uuid(resultObject.getString("openId"))
.token(authToken)
.source(source)
.source(source.toString())
.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")