# 功能描述

实现登录及退出操作。
配置文件为application-login.yml

提示

(1) 需在application.yml中增加spring.profiles.active中增加login才能激活配置文件
(2) 需设置application-login.yml中的sei.cloud.login.enabled为true才能开启login服务

# 配置一览表

#######  登录 配置 ########
sei:
    cloud:
        login:
            enabled: true #设置为true才开启login服务
            pass-url: /*/public/** #不拦截的url(不验证登录),多个url以逗号分隔
            comm-check-code:  #万能验证码
            timeout: 3600 #session过期时间(秒)
            jwt-key:   #jwt的秘钥

            web: #web登录配置
                master: #默认的主项目
                    check-code: true #短信登录时是否需要图形码的验证,默认为false
                    register:
                        enabled: true #是否允许web注册,注意:不是自动注册。true:允许注册,false:关闭注册
                        login: true #注册后立即登录
                        check-logintype: true #检查用户是否允许web登录
                        config: #注册时字段值,与sys_user表字段对应
                            sysid:  #短信注册人员所属系统编号
                            rid:  #短信注册人员的默认角色编号,多个角色逗号分隔
                            oid:  #短信注册人员的默认部门编号,多个部门逗号分隔
                            utype: #用户类型

            sso: #单点登录配置
                master: #默认的主项目
                    enabled: false #设置为true才开启sso登录服务
                    check-logintype: true #检查用户是否允许sso登录
                    config:
                        ip: 127.0.0.1  #允许发出sso登录的服务器IP地址,多个ip之间用逗号分隔
                        home: /#/dashboard #验证成功后的跳转地址
                        login: /noPrivilege.html #验证不成功的跳转地址

            sms: #短信登录配置, 只有一个项目的时候master才有用,多个项目则将master修改为每个项目的名称
                master: #默认的主项目
                    enabled: true #是否开启短信登录
                    check-field: "mobile" #sys_user表验证手机号码字段,uid或mobile字段,默认为uid
                    check-code: true #短信登录时是否需要图形码的验证,默认为false
                    check-double: true #是否检查该手机号对应的系统手机号是否重复,如果重复则不发送短信
                    check-logintype: true #检查用户是否允许短信登录
                    register:
                        enabled: false #是否允许短信注册,即登录时如果用户不存在,则自动注册。true:允许注册,false:关闭注册
                        login: false #注册后立即登录
                        config: #注册时字段值,与sys_user表字段对应
                            sysid:  #短信注册人员所属系统编号
                            rid:  #短信注册人员的默认角色编号,多个角色逗号分隔
                            oid:  #短信注册人员的默认部门编号,多个部门逗号分隔
                            utype: #用户类型
                            status: 1 #用户状态

            weixinPhone: #微信手机号登录
                master: #默认项目的微信配置
                    enabled: true #是否开启微信登录
                    check-field: "uid" #sys_user表验证手机号码字段,uid或mobile字段,默认为uid
                    check-logintype: true #检查用户是否允许微信手机号登录
                    config: #微信配置
                        appid: #微信appid
                        secret:  #微信安全码
                        authentication:  #认证中心,配置通过统一入口获取微信的access_token, 不配置则代表本进程自己获取(单机结构才不配置)
                            security: "" #安全密钥
                            url: "http://127.0.0.1:8081/api/public/getWeixinAccess_token" #统一访问中心地址,不配置则默认为本进程
                    register:
                        enabled: false #是否允许短信注册,即登录时如果用户不存在,则自动注册。true:允许注册,false:关闭注册
                        login: false #注册后立即登录
                        config: #注册时字段值,与sys_user表字段对应
                            sysid:  #短信注册人员所属系统编号
                            rid:  #短信注册人员的默认角色编号,多个角色逗号分隔
                            oid:  #短信注册人员的默认部门编号,多个部门逗号分隔
                            utype: #用户类型

            weixinOpenid: #微信登录
                master: #默认项目的微信配置
                    enabled: false #是否开启微信登录
                    check-field: "uid" #sys_user表验证的字段,uid或mobile字段,默认为uid
                    check-logintype: true #检查用户是否允许微信登录
                    config:
                        appid:   #微信appid
                        secret:  #微信安全码
                        apikey:
                        cache: 0 #缓存微信返回的access_token时间,秒为单位
                    register:
                        enabled: false #是否允许微信注册,即登录时如果用户不存在,则自动注册。true:允许注册,false:关闭注册
                        login: false #注册后立即登录
                        config: #注册时字段值,与sys_user表字段对应
                            sysid:  #短信注册人员所属系统编号
                            rid:  #短信注册人员的默认角色编号,多个角色逗号分隔
                            oid:  #短信注册人员的默认部门编号,多个部门逗号分隔
                            utype: #用户类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

# Service接口

# 第一步 引入包

<dependency>
    <groupId>sei-cloud</groupId>
    <artifactId>login</artifactId>
</dependency>
1
2
3
4

# 第二步 引入接口

@Resource
    LoginService loginService;
1
2

# 第三步 使用接口

/**
 * 系统用户、账户相关服务API
 * @author xiong
 */
public interface LoginService {

    /**
     * 获得所有用户定制的登录事件类
     * @return List | null
     */
    List<LoginEvent> getLoginEvents();

    /**
     * 获得系统数据账套
     * @return List
     */
    List<Map> getDbList();

    /**
     * 设置验证码
     * @param project: 项目编码(与配置文件中项目名称对应,为null则表示主项目或缺省项目)
     */
    void setCheckCode(LoginType loginType, @NonNull String project);

    /**
     * 检测验证码是否正确
     * @param checkCode: 用户输入的验证码(abcd代表不用验证)
     * @return 验证正确返回true, 验证错误返回false
     */
    boolean verificationCheckCode(@NonNull String checkCode);

    /**
     * 发送登录手机短信
     * @param json: 前端请求原始数据
     * json格式:
     * {
     *     mobile: [必须]手机号码
     *     project: [可选]项目编码
     *     action: [可选]操作
     *     service: [可选]短信服务商编码
     *     template: [可选]短信模板
     * }
     * @return ResMsg
     */
    ResMsg sendSms(JSONObject json) throws SQLException, IllegalAccessException;

    /**
     * 登录系统, os参数意义: 1:androd, 2:ios, 3:微信openid, 4:微信手机号, 5:手机短信, 除此之外为web
     * @param json: 前端请求原始数据
     * @return ResMsg
     * @throws Exception 异常
     */
    ResMsg login(@NonNull JSONObject json) throws Exception;

    /**
     * 退出系统
     * @return ResMsg
     * @throws IllegalArgumentException 异常
     * @throws IllegalAccessException 异常
     */
    ResMsg logout() throws IllegalArgumentException, IllegalAccessException;

    /**
     * 检测账号和邮箱是否存在,如果成功则向邮箱发送更改密码的链接地址
     * @param json: 内容
     * @return ResMsg
     * @throws SQLException 异常
     * @throws MessagingException 异常
     */
    ResMsg checkAndSendEmail(@NonNull JSONObject json) throws SQLException, MessagingException;

    /**
     * 检测更改密码的链接地址有效性
     * @param json: 内容
     * @return ResMsg
     */
    ResMsg checkPasswordUrl(@NonNull JSONObject json);

    /**
     * 通过链接地址重置新密码
     * @param json: 内容
     * @return ResMsg
     * @throws SQLException 异常
     */
    ResMsg resetPassword(@NonNull JSONObject json) throws SQLException;

    /**
     * 用户注册
     * @param json: 用户注册数据
     * @return ResMsg
     * @throws Exception 异常
     */
    ResMsg register(@NonNull Object json) throws Exception;

    /**
     * 获取微信接口凭据
     * @param project: 项目编码(为空则采用默认配置)
     * @param code: 微信code
     * @return JSONObject
     */
    JSONObject getWeixinAccessToken(@Nullable String project, @NonNull String code);

    /**
     * 校验微信token
     * @param access_token: 微信token
     * @param openid: 微信openid
     * @return JSONObject
     */
    JSONObject getWeixinValidateData(@NonNull String access_token, @NonNull String openid);

    /**
     * 获得刷新后的token
     * @param project: 微信项目名称(为空则采用默认配置)
     * @param refresh_token: 微信refresh_token
     * @return JSONObject
     */
    JSONObject getWeixinRefreshToken(@Nullable String project, String refresh_token);

    /**
     * 获得微信用户信息
     * @param access_token: 微信token
     * @param openid: 微信openid
     * @return JSONObject
     */
    JSONObject getWeixinUserInfo(@NonNull String access_token, @NonNull String openid);

    /**
     * 注册审核不通过时,验证不登录可修改的url
     * @param json: 参数
     * @return ResMsg
     * @throws SQLException 异常
     */
    ResMsg checkOrgPasswordUrl(@NonNull JSONObject json) throws SQLException;

    /**
     * 获得微信用户手机号码
     * @param json: 微信传回的数据,格式为{code: 加密串}
     * @return: ResMsg
     * @throws IOException 异常
     * @throws NoSuchAlgorithmException 异常
     */
    ResMsg getWeixinMobile(@NonNull JSONObject json) throws IOException, NoSuchAlgorithmException;

    /**
     * 获得微信access_token
     * @param json: 微信传回的项目编号,格式为{projectName: 项目编号}
     * @return ResMsg
     * @throws IOException 异常
     * @throws NoSuchAlgorithmException 异常
     */
    ResMsg getWeixinAccess_token(JSONObject json) throws IOException, NoSuchAlgorithmException;

    /**
     * 获得当前用户当前时间段内可委托的所有账号信息
     * @return ResMsg
     * @throws SQLException
     */
    ResMsg trustUsers() throws SQLException;

    /**
     * 切换委托用户
     * @param json: 前端数据
     * 格式:
     * {
     *      uid: (必配)要切换的用户
     *      os: (选配)1:androd, 2:ios, 3:微信openid, 4:微信手机号, 5:手机短信, 除此之外为web
     *       project: (选配)项目编码
     * }
     * @return ResMsg
     */
    ResMsg trustSwitch(JSONObject json) throws SQLException, IllegalAccessException;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

# Controller接口


@ConditionalOnProperty(name = "sei.cloud.login.enabled", havingValue = "true")
@Api(description = "登录等服务")
@RequestMapping(value = "/api")
public class LoginController {

    List<LoginEvent> getLoginEvents();

    /**
     * 获得系统数据账套
     * @return List
     */
    List<Map> getDbList();

    /**
     * 设置验证码
     * @param project: 项目编码(与配置文件中项目名称对应,为null则表示主项目或缺省项目)
     */
    void setCheckCode(LoginType loginType, @NonNull String project);

    /**
     * 检测验证码是否正确
     * @param checkCode: 用户输入的验证码(abcd代表不用验证)
     * @return 验证正确返回true, 验证错误返回false
     */
    boolean verificationCheckCode(@NonNull String checkCode);

    /**
     * 发送登录手机短信
     * @param json: 前端请求原始数据
     * json格式:
     * {
     *     mobile: [必须]手机号码
     *     project: [可选]项目编码
     *     action: [可选]操作
     *     service: [可选]短信服务商编码
     *     template: [可选]短信模板
     * }
     * @return ResMsg
     */
    ResMsg sendSms(JSONObject json) throws SQLException, IllegalAccessException;

    /**
     * 登录系统, os参数意义: 1:androd, 2:ios, 3:微信openid, 4:微信手机号, 5:手机短信, 除此之外为web
     * @param json: 前端请求原始数据
     * @return ResMsg
     * @throws Exception 异常
     */
    ResMsg login(@NonNull JSONObject json) throws Exception;

    /**
     * 退出系统
     * @return ResMsg
     * @throws IllegalArgumentException 异常
     * @throws IllegalAccessException 异常
     */
    ResMsg logout() throws IllegalArgumentException, IllegalAccessException;

    /**
     * 检测账号和邮箱是否存在,如果成功则向邮箱发送更改密码的链接地址
     * @param json: 内容
     * @return ResMsg
     * @throws SQLException 异常
     * @throws MessagingException 异常
     */
    ResMsg checkAndSendEmail(@NonNull JSONObject json) throws SQLException, MessagingException;

    /**
     * 检测更改密码的链接地址有效性
     * @param json: 内容
     * @return ResMsg
     */
    ResMsg checkPasswordUrl(@NonNull JSONObject json);

    /**
     * 通过链接地址重置新密码
     * @param json: 内容
     * @return ResMsg
     * @throws SQLException 异常
     */
    ResMsg resetPassword(@NonNull JSONObject json) throws SQLException;

    /**
     * 用户注册
     * @param json: 用户注册数据
     * @return ResMsg
     * @throws Exception 异常
     */
    ResMsg register(@NonNull Object json) throws Exception;

    /**
     * 获取微信接口凭据
     * @param project: 项目编码(为空则采用默认配置)
     * @param code: 微信code
     * @return JSONObject
     */
    JSONObject getWeixinAccessToken(@Nullable String project, @NonNull String code);

    /**
     * 校验微信token
     * @param access_token: 微信token
     * @param openid: 微信openid
     * @return JSONObject
     */
    JSONObject getWeixinValidateData(@NonNull String access_token, @NonNull String openid);

    /**
     * 获得刷新后的token
     * @param project: 微信项目名称(为空则采用默认配置)
     * @param refresh_token: 微信refresh_token
     * @return JSONObject
     */
    JSONObject getWeixinRefreshToken(@Nullable String project, String refresh_token);

    /**
     * 获得微信用户信息
     * @param access_token: 微信token
     * @param openid: 微信openid
     * @return JSONObject
     */
    JSONObject getWeixinUserInfo(@NonNull String access_token, @NonNull String openid);

    /**
     * 注册审核不通过时,验证不登录可修改的url
     * @param json: 参数
     * @return ResMsg
     * @throws SQLException 异常
     */
    ResMsg checkOrgPasswordUrl(@NonNull JSONObject json) throws SQLException;

    /**
     * 获得微信用户手机号码
     * @param json: 微信传回的数据,格式为{code: 加密串}
     * @return: ResMsg
     * @throws IOException 异常
     * @throws NoSuchAlgorithmException 异常
     */
    ResMsg getWeixinMobile(@NonNull JSONObject json) throws IOException, NoSuchAlgorithmException;

    /**
     * 获得微信access_token
     * @param json: 微信传回的项目编号,格式为{projectName: 项目编号}
     * @return ResMsg
     * @throws IOException 异常
     * @throws NoSuchAlgorithmException 异常
     */
    ResMsg getWeixinAccess_token(JSONObject json) throws IOException, NoSuchAlgorithmException;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

# 框架登录事件

使用时通过继承本类实现对操作成功的回调。

/**
 * 框架登录事件
 * @author xiong
 */
public abstract class LoginEvent {

    /**
     * 登录前的回调
     * @param loginType: 登录类型
     * @param project: 项目编码
     * @param json: 前端请求的原始数据
     * @param resMsg: 返回前端的数据
     * @return boolean true: 继续验证, false: 终止操作并返回前端resMsg
     */
    public boolean login_before(LoginType loginType, String project, JSONObject json, ResMsg resMsg) {
        return true;
    }

    /**
     * 完成用户登录后的回调
     * @param loginType: 登录类型
     * @param project: 项目编码
     * @param sessionUser: 当前用户信息,不为空代表登录验证成功
     * @param json: 前端请求的原始数据
     * @param resMsg: 返回前端的数据
     */
    public void login_After(LoginType loginType, String project, SessionUser sessionUser, JSONObject json, ResMsg resMsg) {

    }

    /**
     * 替换默认的注册用户
     * @param loginType: 登录类型
     * @param project: 项目编码
     * @param filedValues: 字段及值
     * @param json: 前端请求的原始数据
     * @param resMsg: 返回前端的数据
     * @return boolean 为false则终止后续操作
     */
    public boolean register(LoginType loginType, String project, JSONObject filedValues, JSONObject json, ResMsg resMsg) throws Exception {
        return true;
    }

    /**
     * 完成用户退出后的回调
     * @param sessionUser: session中的用户信息
     */
    public void logOut(SessionUser sessionUser){

    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51