懒羊羊
2023-08-30 71e81ed1d12e4d69f53c8ad9e066650ad4186293
提交 | 用户 | 时间
71e81e 1 /**
2  * Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
3  * <p>
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * <p>
8  * http://www.apache.org/licenses/LICENSE-2.0
9  * <p>
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package cn.stylefeng.guns.sys.modular.system.controller;
17
18 import cn.stylefeng.guns.base.auth.context.LoginContextHolder;
19 import cn.stylefeng.guns.base.auth.model.LoginUser;
20 import cn.stylefeng.guns.base.auth.service.AuthService;
21 import cn.stylefeng.guns.base.consts.ConstantsContext;
22 import cn.stylefeng.guns.base.tenant.context.DataBaseNameHolder;
23 import cn.stylefeng.guns.base.tenant.context.TenantCodeHolder;
24 import cn.stylefeng.guns.base.tenant.entity.TenantInfo;
25 import cn.stylefeng.guns.base.tenant.service.TenantInfoService;
26 import cn.stylefeng.guns.sys.core.auth.cache.SessionManager;
27 import cn.stylefeng.guns.sys.core.exception.InvalidKaptchaException;
28 import cn.stylefeng.guns.sys.core.exception.enums.BizExceptionEnum;
29 import cn.stylefeng.guns.sys.modular.system.service.UserService;
30 import cn.stylefeng.roses.core.base.controller.BaseController;
31 import cn.stylefeng.roses.core.mutidatasource.DataSourceContextHolder;
32 import cn.stylefeng.roses.core.util.SpringContextHolder;
33 import cn.stylefeng.roses.core.util.ToolUtil;
34 import cn.stylefeng.roses.kernel.model.exception.RequestEmptyException;
35 import cn.stylefeng.roses.kernel.model.exception.ServiceException;
36 import cn.stylefeng.roses.kernel.model.response.ResponseData;
37 import cn.stylefeng.roses.kernel.model.response.SuccessResponseData;
38 import com.google.code.kaptcha.Constants;
39 import org.springframework.beans.factory.annotation.Autowired;
40 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
41 import org.springframework.security.core.context.SecurityContextHolder;
42 import org.springframework.stereotype.Controller;
43 import org.springframework.ui.Model;
44 import org.springframework.web.bind.annotation.RequestMapping;
45 import org.springframework.web.bind.annotation.RequestMethod;
46 import org.springframework.web.bind.annotation.RequestParam;
47 import org.springframework.web.bind.annotation.ResponseBody;
48
49 import javax.servlet.http.HttpServletRequest;
50 import javax.servlet.http.HttpServletResponse;
51 import java.util.Map;
52
53 /**
54  * 登录控制器
55  *
56  * @author fengshuonan
57  * @Date 2017年1月10日 下午8:25:24
58  */
59 @Controller
60 public class LoginController extends BaseController {
61
62     @Autowired
63     private AuthService authService;
64
65     @Autowired
66     private UserService userService;
67
68     @Autowired
69     private SessionManager sessionManager;
70
71     /**
72      * 跳转到主页
73      *
74      * @author fengshuonan
75      * @Date 2018/12/23 5:41 PM
76      */
77     @RequestMapping(value = "/", method = RequestMethod.GET)
78     public String index(Model model) {
79
80         //判断用户是否登录
81         if (LoginContextHolder.getContext().hasLogin()) {
82             Map<String, Object> userIndexInfo = userService.getUserIndexInfo();
83
84             //用户信息为空,提示账号没分配角色登录不进去
85             if (userIndexInfo == null) {
86                 model.addAttribute("tips", "该用户没有角色,无法登陆");
87                 return "/login.html";
88             } else {
89                 model.addAllAttributes(userIndexInfo);
90                 return "/index.html";
91             }
92
93         } else {
94             return "/login.html";
95         }
96     }
97
98     /**
99      * 跳转到登录页面
100      *
101      * @author fengshuonan
102      * @Date 2018/12/23 5:41 PM
103      */
104     @RequestMapping(value = "/login", method = RequestMethod.GET)
105     public String login() {
106         if (LoginContextHolder.getContext().hasLogin()) {
107             return REDIRECT + "/";
108         } else {
109             return "/login.html";
110         }
111     }
112
113     /**
114      * 点击登录执行的动作
115      *
116      * @author fengshuonan
117      * @Date 2018/12/23 5:42 PM
118      */
119     @RequestMapping(value = "/login", method = RequestMethod.POST)
120     @ResponseBody
121     public ResponseData loginVali(HttpServletRequest request, HttpServletResponse response) {
122
123         String username = super.getPara("username");
124         String password = super.getPara("password");
125
126         if (ToolUtil.isOneEmpty(username, password)) {
127             throw new RequestEmptyException("账号或密码为空!");
128         }
129
130         //如果系统开启了多租户开关,则添加租户的临时缓存
131         if (ConstantsContext.getTenantOpen()) {
132             String tenantCode = super.getPara("tenantCode");
133             if (ToolUtil.isNotEmpty(tenantCode)) {
134
135                 //从spring容器中获取service,如果没开多租户功能,没引入相关包,这里会报错
136                 TenantInfoService tenantInfoService = null;
137                 try {
138                     tenantInfoService = SpringContextHolder.getBean(TenantInfoService.class);
139                 } catch (Exception e) {
140                     throw new ServiceException(500, "找不到多租户service,请检查是否引入guns-tenant模块!");
141                 }
142
143                 //获取租户信息
144                 TenantInfo tenantInfo = tenantInfoService.getByCode(tenantCode);
145                 if (tenantInfo != null) {
146                     String dbName = tenantInfo.getDbName();
147
148                     //添加临时变量(注意销毁)
149                     TenantCodeHolder.put(tenantCode);
150                     DataBaseNameHolder.put(dbName);
151                     DataSourceContextHolder.setDataSourceType(dbName);
152                 } else {
153                     throw new ServiceException(BizExceptionEnum.NO_TENANT_ERROR);
154                 }
155             }
156         }
157
158         //验证验证码是否正确
159         if (ConstantsContext.getKaptchaOpen()) {
160             String kaptcha = super.getPara("kaptcha").trim();
161             String code = (String) super.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
162             if (ToolUtil.isEmpty(kaptcha) || !kaptcha.equalsIgnoreCase(code)) {
163                 throw new InvalidKaptchaException();
164             }
165         }
166
167         //登录并创建token
168         String token = authService.login(username, password);
169
170         return new SuccessResponseData(token);
171     }
172
173     /**
174      * 利用已有的token进行登录(一般用在oauth登录)
175      *
176      * @author fengshuonan
177      * @Date 2018/12/23 5:42 PM
178      */
179     @RequestMapping(value = "/sysTokenLogin")
180     public String sysTokenLogin(@RequestParam(value = "token", required = false) String token, Model model) {
181         if (ToolUtil.isNotEmpty(token)) {
182
183             //从session获取用户信息,没有就是token无效
184             LoginUser user = sessionManager.getSession(token);
185             if (user == null) {
186                 return "/login.html";
187             }
188
189             //创建当前登录上下文
190             UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
191                     user, null, user.getAuthorities());
192             SecurityContextHolder.getContext().setAuthentication(authentication);
193
194             //渲染首页需要的用户信息
195             Map<String, Object> userIndexInfo = userService.getUserIndexInfo();
196             if (userIndexInfo == null) {
197                 model.addAttribute("tips", "该用户没有角色,无法登陆!");
198                 return "/login.html";
199             } else {
200                 model.addAllAttributes(userIndexInfo);
201             }
202
203             //创建cookie
204             authService.addLoginCookie(token);
205
206             return "/index.html";
207         } else {
208             model.addAttribute("tips", "token请求为空,无法登录!");
209             return "/login.html";
210         }
211     }
212
213     /**
214      * 退出登录
215      *
216      * @author fengshuonan
217      * @Date 2018/12/23 5:42 PM
218      */
219     @RequestMapping(value = "/logout")
220     @ResponseBody
221     public ResponseData logOut() {
222         authService.logout();
223         return new SuccessResponseData();
224     }
225
226 }