前后端分离项目 springboot+ant design pro of vue(4)
前后端分离项目 前后端整合
前后端项目整合
目录
前端,去掉mock
直接注释或删除main.js中引入的mock.js就可以
去掉之后前端肯定请求报错,接下来就是设置跨域
设置跨域
这段,前端项目都给写好了,打开就可以
最后,我的修改成这样,port是前端项目端口,target是后端请求路径
devServer: {
// development server port 8000
port: 8001,
// If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
proxy: {
'/api': {
target: 'http://localhost:8080',
ws: false,
changeOrigin: true,
pathRewrite: { // 路径重写,
'^/api': '' // 替换target中的请求地址,也就是说以后你在请求http://api.codingmore.top/v2/XXXXX这个地址的时候直接写成/api即可。
}
}
}
},
后端设置
package com.han.springbootshiro.config.shiro;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Configuration
public class CorsConfig implements Filter {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 允许任何域名使用
corsConfiguration.addAllowedOriginPattern("*");
// 允许任何头
corsConfiguration.addAllowedHeader("*");
// 允许任何方法(post、get等)
corsConfiguration.addAllowedMethod("*");
//允许cookie
corsConfiguration.setAllowCredentials(true);// 是否支持安全证书(必需参数)
corsConfiguration.setMaxAge(3600L);// 预检请求的有效期,单位为秒。
corsConfiguration.addExposedHeader("set-cookie");
corsConfiguration.addExposedHeader("access-control-allow-headers");
corsConfiguration.addExposedHeader("access-control-allow-methods");
corsConfiguration.addExposedHeader("access-control-allow-origin");
corsConfiguration.addExposedHeader("access-control-max-age");
corsConfiguration.addExposedHeader("X-Frame-Options");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// 对接口配置跨域设置
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpStatus.NO_CONTENT.value());
return;
} else {
filterChain.doFilter(request, response);
}
}
@Bean
public FilterRegistrationBean replaceTokenFilter(){
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter( new CorsConfig ());
registration.addUrlPatterns("/*");
registration.setName("crosFilter ");
registration.setOrder(1);
return registration;
}
}
修改前端登录请求路径
修改 src/api/login.js 中请求路径,修改成自己的项目请求路径就可以了,我的是这样
export function login (parameter) {
return request({
url: '/system/user/login',
method: 'post',
data: parameter
})
}
export function getInfo () {
return request({
url: '/system/user/userInfo',
method: 'get'
})
}
export function logout () {
return request({
url: '/system/user/logout',
method: 'get'
})
}
注意请求方式要和后端一致,就是method,我的后端方法使get请求方式,所以还需要修改一下
@PostMapping("login")
public Result login(@RequestBody User user){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
subject.login(usernamePasswordToken);
return new Result().success().setData(subject.getSession().getId());
}
现在登录的话,会发现 即使输入正确的用户名密码,后端也会报错
是因为前端密码进行了md5加密,加密后密码肯定与数据库密码匹配不上
删除加密就好了,要是有需要,可以在整合完毕后再加
全局异常处理
刚才登录错误的时候,前端提示的直接是后端的报错信息,这个不是我们想要的,在后端进行统一的异常处理
package com.han.springbootshiro.aop;
import com.han.springbootshiro.common.Result;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @author han
*/
@RestControllerAdvice
public class GloabException {
@ExceptionHandler(UnknownAccountException.class)
public Result handler(UnknownAccountException unknownAccountException){
Result<Object> result = new Result().error();
result.setMsg("未知用户");
return result;
}
@ExceptionHandler(IncorrectCredentialsException.class)
public Result handler(IncorrectCredentialsException incorrectCredentialsException){
Result<Object> result = new Result().error();
result.setMsg("密码错误");
return result;
}
@ExceptionHandler(Exception.class)
public Result handler(Exception exception){
Result<Object> result = new Result().error();
result.setMsg("网络错误");
return result;
}
}
我只定义了这几个异常,大家有需要,可以自行增加
改代码
再次登录,发现提示信息也不是我们后端返回的msg
继续 修改
src/utils/request.js
封装的request中有响应拦截器,在拦截器中做一下修改
// response interceptor
request.interceptors.response.use((response) => {
const { code, msg, data } = response.data
if (code !== 200) {
if (code === 401) {
store.dispatch('Logout').then(() => {
this.$router.push('/user/login')
})
}
const errorMsg = msg || '未知错误'
// eslint-disable-next-line no-undef
return Promise.reject(errorMsg)
} else {
return data
}
}, errorHandler)
发起请求返回的code只要不是200,我们就认为报错了,把报错信息返回去,也就是msg,否则正常返回data中数据就可以。
login.vue
请求失败的方法,err本身就是 错误信息
所以修改成这样就可以了
requestFailed (err) {
this.isLoginError = true
this.$notification['error']({
message: '错误',
description: err || '请求出现错误,请稍后再试',
duration: 4
})
}
现在用户名密码错误的话,错误提示信息正确,但是用户名密码正确的话,一直报错。。。。很无奈,
找了半天,发现用户名密码正确的情况下一直走的是requestFailed (err) 方法,
看返回的code是200没错,找了半天才发现是在Login方法里报错了,这个reponse其实就是data,这个方法后端直接返回的是个sessionid,data.result应该是这个报错,修改一下
修改完后是这样,如果跟我返回的信息不一样,可以自己打日志,按照自己的代码修改
// 登录
Login ({ commit }, userInfo) {
return new Promise((resolve, reject) => {
login(userInfo).then(response => {
console.log(response)
const result = response
storage.set(ACCESS_TOKEN, result, new Date().getTime() + 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result)
resolve()
}).catch(error => {
reject(error)
})
})
},
修改之后,报错变了,现在是请求用户信息失败,好,接着修改
看一下后台报错,
Request method 'GET' not supported,
请求方式有问题,修改请求方式,
依然报错,看前端控制台,返回数据正常,而且是调用了userInfo之后,又调用了logOut方法,应该是获取到userInfo信息之后,解析异常
在userInfo中打印一下返回的信息
发现自己返回的信息中没有result,修改 const result = response
// 获取用户信息
GetInfo ({ commit }) {
return new Promise((resolve, reject) => {
getInfo().then(response => {
const result = response
if (result.permissions && result.permissions.length > 0) {
const permissions = result.permissions
commit('SET_PERMISSIONS', permissions)
commit('SET_INFO', result)
} else {
reject(new Error('getInfo: roles must be a non-null array !'))
}
commit('SET_NAME', { name: result.name, welcome: welcome() })
commit('SET_AVATAR', result.avatar)
resolve(response)
}).catch(error => {
reject(error)
})
})
},
再次登录,跳转到了404页面,看一下控制台打印的路由跳转信息,先是跳转到/dashboard/workplace,然后跳转到404页面,这样应该是没有权限造成的,
我们可以定义一个不需要权限的空页面,或者没有权限不让他登录就可以 router.config.js
Empty是来自ant design vue 的一个空组件
还有permission.js中登录后默认跳转路由也改一下
修改完后登录是这样
如果需要展示其他页面,可以把router.config.js 中对应页面的权限删掉就可以了
或者可以在数据库给对应角色加上权限就可以了
需要新增页面的,也是在router.config.js中编写路由,导入对应的组件,这里不在展示
到现在,前后端分离算是整合完毕
在下一步是整合redis做shiro缓存,会话管理,然后就是密码加密
更多推荐
所有评论(0)