使用oauth2

如果第三方应用和本开放平台对接时需要获取用户隐私数据(如商品、订单),为为了安全与隐私,第三方应用需要取得用户的授权,即获取访问用户数据的授权令牌 AccessToken 。这种情况下,第三方应用需要引导用户完成帐号“登录授权”的流程。

easyopen从1.2.0版本开始支持oauth2认证。接入方式很简单:

  • 新建一个Oauth2ManagerImpl类,实现Oauth2Manager接口
  • 用户类实现OpenUser接口。
    1. @Service
    2. public class Oauth2ManagerImpl implements Oauth2Manager {
    3. ...
    4. }
    5. public class User implements OpenUser {
    6. ...
    7. }

因为对于accessToken的管理每个开发人员所用的方式都不一样,所以需要自己来实现。

  • Oauth2Manager接口定义如下:

    1. public interface Oauth2Manager {
    2. /**
    3. * 添加 auth code
    4. *
    5. * @param authCode
    6. * code值
    7. * @param authUser
    8. * 用户
    9. */
    10. void addAuthCode(String authCode, OpenUser authUser);
    11. /**
    12. * 添加 access token
    13. *
    14. * @param accessToken
    15. * token值
    16. * @param authUser
    17. * 用户
    18. * @param expiresIn 时长,秒
    19. */
    20. void addAccessToken(String accessToken, OpenUser authUser, long expiresIn);
    21. /**
    22. * 验证auth code是否有效
    23. *
    24. * @param authCode
    25. * @return 无效返回false
    26. */
    27. boolean checkAuthCode(String authCode);
    28. /**
    29. * 根据auth code获取用户
    30. *
    31. * @param authCode
    32. * @return 返回用户
    33. */
    34. OpenUser getUserByAuthCode(String authCode);
    35. /**
    36. * 根据access token获取用户名
    37. *
    38. * @param accessToken
    39. * token值
    40. * @return 返回用户
    41. */
    42. OpenUser getUserByAccessToken(String accessToken);
    43. /**
    44. * 获取auth code / access token 过期时间
    45. *
    46. * @return
    47. */
    48. long getExpireIn(ApiConfig apiConfig);
    49. /**
    50. * 用户登录,需判断是否已经登录
    51. * @param request
    52. * @return 返回用户对象
    53. */
    54. OpenUser login(HttpServletRequest request) throws LoginErrorException;
    55. }

accessToken获取流程

  • 第一步获取code

    1. 1、首先通过如http://localhost:8080/api/authorize?client_id=test&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth2callback访问授权页面;
    2. 2、该控制器首先检查clientId是否正确;如果错误将返回相应的错误信息;
    3. 3、然后判断用户是否登录了,如果没有登录首先到登录页面登录;
    4. 4、登录成功后生成相应的code即授权码,然后重定向到客户端地址,如http://localhost:8080/oauth2callback?code=6d250650831fea227749f49a5b49ccad;在重定向到的地址中会带上code参数(授权码),接着客户端可以根据授权码去换取accessToken。
  • 第二步通过code换取accessToken

    1. 1、首先通过如http://localhost:8080/api/accessToken,POST提交如下数据访问:
    2. code:6d250650831fea227749f49a5b49ccad
    3. client_id:test
    4. client_secret:123456
    5. grant_type:authorization_code
    6. redirect_uri:http://localhost:8080/api/authorize
    7. 2、服务器会验证client_idclient_secretcode的正确性,如果错误会返回相应的错误;
    8. 3、如果验证通过会生成并返回相应的访问令牌accessToken
    9. {
    10. "access_token": "01e111c0d3c8e415fea038d5c64432ef",
    11. "refresh_token": "d1165b75d386b3ef1bd0423b4e3bfef9",
    12. "token_type": "Bearer",
    13. "expires_in": 7200,
    14. "username": "admin"
    15. }

以上两个步骤需要在客户端上实现。示例项目easyopen-server上有个例子可以参考,启动服务,然后访问http://localhost:8080/go_oauth2

获取accessToken用户:

  1. // 拿到accessToken用户
  2. OpenUser user = ApiContext.getAccessTokenUser();

使用refreshToken刷新accessToken

accessToken有过期时间,为了防止过期可以通过refreshToken来换取新的accessToken,方便后续接口调用。

  1. 1. 首先通过如http://localhost:8080/api/accessToken,POST提交如下数据访问:
  2. refresh_token:你的refreshToken
  3. client_id:test
  4. client_secret:123456
  5. grant_type:refresh_token
  6. 2. 服务器会验证client_idclient_secretrefresh_token的正确性,如果错误会返回相应的错误;
  7. 3. 如果验证通过会生成并返回新的访问令牌accessToken和新的refreshToken
  8. 返回结果:
  9. {
  10. "access_token": "01e111c0d3c8e415fea038d5c64432ef",
  11. "refresh_token": "d1165b75d386b3ef1bd0423b4e3bfef9",
  12. "token_type": "Bearer",
  13. "expires_in": 7200,
  14. "username": "admin"
  15. }

成功换取新的accessToken和refreshToken后,老的accessToken和refreshToken不能使用。