一、前端部分
1.创建一个Vue-Cli项目
2.安装axios、qs、element-ui依赖
npm install qs // 安装qs
npm install axios // 安装axios
npm i element-ui -S // 安装elementUI
3. 配置main.js文件
tips:设置了原型后,在我们后面的代码编写中,可以直接通过this.的方式来调用我们安装的axios和qs。
import Vue from 'vue'
import App from './App.vue'
import router from './router'
//引入ElementUI
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
//引入axios
import axios from "axios";
//引入qs
import qs from "qs"
Vue.use(ElementUI)
//设置原型
Vue.prototype.axios = axios;
Vue.prototype.qs = qs;
//给axios定义基础路径
Vue.prototype.axios.defaults.baseURL = "http://localhost:8888";
//携带cookie
Vue.prototype.axios.defaults.withCredentials = true;
Vue.config.productionTip = false
new Vue({
router,
render: function (h) { return h(App) }
}).$mount('#app')
4.登录的代码
<template>
<div id="login">
<el-card>
<span style="color:red">{{error}}</span>
<el-form ref="form" :model="user" label-width="80px">
<el-form-item label="账号">
<el-input v-model="user.username"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input type="password" v-model="user.password"></el-input>
</el-form-item>
<el-form-item label="记住我">
<el-checkbox v-model="user.rememberMe"></el-checkbox>
</el-form-item>
<el-form-item >
<el-button type="primary" @click="login">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
export default {
name: "Login",
data(){
return{
//登录用户数据
user:{username:"",password:"",rememberMe:false},
error:"" //错误信息
}
},
methods:{
//登录
login(){
this.axios.post("/doLogin",
this.qs.stringify(this.user))//qs将json格式转为表单格式
.then(res => {
console.log(res.data);
//判断是否返回了用户信息
if(res.data.username){
this.$router.push("/index")
}else{
this.error = res.data.msg;
}
});
}
}
}
</script>
<style scoped>
#login{
width: 480px;
height: 300px;
margin: 200px auto;
}
</style>
一、后台部分
因为我们是前后端分离的项目所以可能出现跨域的问题,我们解决的方法就是在配置类中来进行跨域的配置,并且因为是SpringSecurity项目所以当我们axios请求的时候无法获取到登录对象的session,所以我们也需要配置axios携带cookie,以达到能访问session的目的。
package com.smz.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
public static final String CONTENT_TYPE = "application/json;charset=UTF-8";
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JdbcTokenRepositoryImpl jdbcTokenRepository;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/page/login.html","/js/**","/css/**").permitAll()
.antMatchers("/page/**").hasRole("管理员") //必须有对应角色才能访问
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/page/login.html")
.loginProcessingUrl("/doLogin")
.successHandler((req,resp,auth)->{
resp.setContentType(CONTENT_TYPE);
Object principal = auth.getPrincipal();
resp.getWriter().print(new ObjectMapper().writeValueAsString(principal));
resp.getWriter().close();
})
.failureHandler((req,resp,auth)->{
resp.setContentType(CONTENT_TYPE);
resp.getWriter().print("{\"msg\":\"账号或密码错误\"}");
resp.getWriter().close();
})
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler((req,resp,auth) -> {
resp.setContentType(CONTENT_TYPE);
resp.getWriter().print("{\"msg\":\"注销成功\"}");
resp.getWriter().close();
})
.and()
.rememberMe()
.rememberMeParameter("rememberMe")
.tokenRepository(jdbcTokenRepository)
.tokenValiditySeconds(24 * 3600)
.and()
.cors() //跨域配置
.and()
.csrf().disable();
//配置http解决iframe不能跳转的问题
http.headers().frameOptions().sameOrigin().httpStrictTransportSecurity().disable();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
// 解决跨域问题
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:8080"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
// 允许携带cookie
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
重点是这部分的代码