解刨SOLO认证流程

Published on with 0 views and 0 comments

0.要搞个东西呀所以不得不解析一下代码。一行一行走

1.开始

  image.png
点击开始使用时调用

 1@RequestProcessing(value = "/login/redirect", method = HttpMethod.GET)
 2    public void redirectAuth(final RequestContext context) {
 3	// 从当前域里拿到站点地址
 4        String referer = context.param("referer");
 5        if (StringUtils.isBlank(referer)) {
 6            referer = Latkes.getServePath();
 7        }
 8	// 生成一个16位随机的东西然后跟入站点地址
 9        String state = RandomStringUtils.randomAlphanumeric(16) + referer;
10	// 放到集合里
11        STATES.add(state);
12	// 构造 请求url 请求hacpai,回调/login/callback
13        final String loginAuthURL = "https://hacpai.com/login?goto=" + Latkes.getServePath() + "/login/callback";
14	// 加入state
15        final String path = loginAuthURL + "?state=" + URLs.encode(state);
16        // 重定向
17	context.sendRedirect(path);
18    }

2.进入 HacPai

  猜一下
1.输入用户名密码
2.查询用户信息
3.截取 goto 路径
4.重定向 http://站点?state=state&userId=userId&userName=userName

3.返回站点

 1 @RequestProcessing(value = "/login/callback", method = HttpMethod.GET)
 2   // `synchronized` 或许是为了极端情况下1000000人跑这个东西然后你拿着我的东西登进去了?
 3    public synchronized void authCallback(final RequestContext context) {
 4	// 首先验证state是不是本站发出的
 5        String state = context.param("state");
 6        if (!STATES.contains(state)) {
 7            context.sendError(400);
 8
 9            return;
10        }
11	// 是的话就删了,免得被人用了
12        STATES.remove(state);
13        String referer = URLs.decode(state);
14	// 从第16位截取出站点地址
15        referer = StringUtils.substring(referer, 16);
16
17        final Response response = context.getResponse();
18        final Request request = context.getRequest();
19	// 拿到用户ID,名称,头像,我头像贼帅
20        final String openId = context.param("userId");
21        final String userName = context.param(User.USER_NAME);
22        final String userAvatar = context.param("avatar");
23	// 看看是不是有这个用户啊
24        JSONObject user = userQueryService.getUserByGitHubId(openId);
25	// 如果没有
26        if (null == user) {
27		// 是不是没初始化博客呢还,没初始化就初始化
28            if (!initService.isInited()) {
29                final JSONObject initReq = new JSONObject();
30                initReq.put(User.USER_NAME, userName);
31                initReq.put(UserExt.USER_AVATAR, userAvatar);
32                initReq.put(UserExt.USER_B3_KEY, openId);
33                initReq.put(UserExt.USER_GITHUB_ID, openId);
34                initService.init(initReq);
35            } else {
36                user = userQueryService.getUserByName(userName);
37                if (null == user) {
38                    final JSONObject addUserReq = new JSONObject();
39                    addUserReq.put(User.USER_NAME, userName);
40                    addUserReq.put(UserExt.USER_AVATAR, userAvatar);
41                    addUserReq.put(User.USER_ROLE, Role.VISITOR_ROLE);
42                    addUserReq.put(UserExt.USER_GITHUB_ID, openId);
43                    addUserReq.put(UserExt.USER_B3_KEY, openId);
44                    try {
45			// 这我估计是加到用户列表里去了,没往下看了
46                        userMgmtService.addUser(addUserReq);
47                    } catch (final Exception e) {
48                        LOGGER.log(Level.ERROR, "Registers via oauth failed", e);
49                        context.sendError(500);
50
51                        return;
52                    }
53                } else {
54                    user.put(UserExt.USER_GITHUB_ID, openId);
55                    user.put(User.USER_NAME, userName);
56                    user.put(UserExt.USER_AVATAR, userAvatar);
57                    try {
58                        userMgmtService.updateUser(user);
59                    } catch (final Exception e) {
60                        LOGGER.log(Level.ERROR, "Updates user GitHub id failed", e);
61                        context.sendError(500);
62
63                        return;
64                    }
65                }
66            }
67        } else {
68            user.put(User.USER_NAME, userName);
69            user.put(UserExt.USER_AVATAR, userAvatar);
70            try {
71                userMgmtService.updateUser(user);
72            } catch (final Exception e) {
73                LOGGER.log(Level.ERROR, "Updates user name failed", e);
74                context.sendError(500);
75
76                return;
77            }
78        }
79	
80        user = userQueryService.getUserByName(userName);
81        if (null == user) {
82            LOGGER.log(Level.WARN, "Can't get user by name [" + userName + "]");
83            context.sendError(404);
84
85            return;
86        }
87// 如果通过了校验,那就登录
88        Solos.login(user, response);
89        context.sendRedirect(referer);
90        LOGGER.log(Level.INFO, "Logged in [name={0}, remoteAddr={1}] with oauth", userName, Requests.getRemoteAddr(request));
91    }

  4.造 Cookie

 1public static void login(final JSONObject user, final Response response) {
 2        try {
 3	// 获取用户ID,如果没有就用Kes.OBJECT_ID:oId
 4            final String userId = user.optString(Keys.OBJECT_ID);
 5            final JSONObject cookieJSONObject = new JSONObject();
 6	 // map放userId进oid建
 7            cookieJSONObject.put(Keys.OBJECT_ID, userId);
 8            final String b3Key = user.optString(UserExt.USER_B3_KEY);
 9	// 生成一个8位的带数字和字母的随机字符串
10            final String random = RandomStringUtils.randomAlphanumeric(8);
11	// emmm,Token b3key+随机字符串,存入MAP(原先是有密码混入的呦)
12            cookieJSONObject.put(Keys.TOKEN, b3Key + ":" + random);
13	// AES 加密 JSON的toString,key为lake配置文件中的cookieSecret,如果没有配置,那就是8位随机数字+字母字符串
14            final String cookieValue = Crypts.encryptByAES(cookieJSONObject.toString(), COOKIE_SECRET);
15// cookie: io.netty.handler.codec.http.cookie.Cookie cookie;
16// CookieNAME:lake配置中的cookieName如果没有那就是随机的
17//cookieValue是刚才那个MapToSring混入COOKIE_SECRET然后AES加密后的
18            final Cookie cookie = new Cookie(COOKIE_NAME, cookieValue);
19	// Cookie时间限制
20            cookie.setMaxAge(COOKIE_EXPIRY);
21	// Cookie路径
22            cookie.setPath("/");
23      // 我不知道这是啥
24            cookie.setHttpOnly(true);
25	// 放入Response中
26            response.addCookie(cookie);
27        } catch (final Exception e) {
28            LOGGER.log(Level.WARN, "Can not write cookie", e);
29        }
30    }

  5.然后重定向到主页


标题:解刨SOLO认证流程
作者:fe
地址:https://blog.eiyouhe.com/articles/2019/12/23/1577104532633.html