1.项目目录
优化一下早上的登录拦截!!!
config负责配置文件
eureka负责注册中心
pojo负责实体类
teacher负责teacher相关服务
user负责user相关服务
utils负责工具类
zuul网关
2.config
2.1 pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.2 application.yml
server:
port: 9000
spring:
application:
name: live_config
profiles:
active: native
cloud:
config:
server:
native:
search-locations: classpath:properties/
eureka:
client:
service-url:
defaultZone: http://localhost:8888/eureka
2.3 live-config-dev.pro[erties
#数据库连接信息
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/qf?useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
#jpa
spring.jpa.database=mysql
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
#ribbon配置
ribbon.ReadTimeout=5000
#ribbon的连接超时时间
ribbon.ConnectTimeout=5000
#hystrix与feign结合的配置
feign.hystrix.enabled=true
#加密密钥
live.scertKey=fb2c664dc9d7e06ad6b3cbd3251ef3c4
2.4 启动类
@SpringBootApplication
//标志当前为config服务端
@EnableConfigServer
//标志当前为eureka客户端
@EnableEurekaClient
3. eureka
3.1 pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
3.2 bootstrap.yml
server:
port: 8888
spring:
application:
name: live_eureka
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8888/eureka
server:
#关闭自我保护机制
enable-self-preservation: false
3.3 启动类
@SpringBootApplication
//标志当前类为eureka服务端
@EnableEurekaServer
4.pojo
4.1 pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
4.2 实体类
User
@Data
@Entity
@Table(name = "User")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String password;
}
TbTeacher
@Data
@Entity
@Table(name="tb_teacher")
public class TbTeacher {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birth;
private Double score;
}
BaseResp
@Data
public class BaseResp {
private Long code;
private Object message;
private Long total;
}
5.teacher
5.1 pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.wo</groupId>
<artifactId>live_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
5.2 bootstrap.yml
server:
port: 8001
spring:
application:
name: live-teacher
cloud:
config:
discovery:
service-id: live_config
enabled: true
name: live-config
profile: dev
eureka:
client:
service-url:
defaultZone: http://localhost:8888/eureka
5.3 启动类
@SpringBootApplication//(exclude = {DataSourceAutoConfiguration.class})
//eureka,config的客户端
@EnableDiscoveryClient
5.4 controller
@RestController
public class TeacherController {
@Autowired
TeacherService teacherService;
@RequestMapping("/findAll")
public List<TbTeacher> findAll(){
return teacherService.findAll();
}
}
6.user
6.1 pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.wo</groupId>
<artifactId>live_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.wo</groupId>
<artifactId>live_utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
6.2 bootstrap.yml
server:
port: 8002
spring:
application:
name: live-user
cloud:
config:
discovery:
service-id: live_config
enabled: true
name: live-config
profile: dev
eureka:
client:
service-url:
defaultZone: http://localhost:8888/eureka
6.3 启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
6.4 com.wo下的包
1.client
@FeignClient(serviceId = "live-teacher")
public interface TeacherClient {
@RequestMapping("/findAll")
public List<TbTeacher> findAll();
}
2.dao
public interface UserRepository extends JpaRepository<User,Integer>{
User findByNameAndPassword(String name, String password);
}
3.service
public interface UserService {
BaseResp findByNameAndPassword(String name, String password);
BaseResp findTeacher(String token);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserRepository userRepository;
@Autowired
JWTUtils jwtUtils;
@Autowired
TeacherClient teacherClient;
@Override
public BaseResp findByNameAndPassword(String name, String password) {
BaseResp baseResp=new BaseResp();
if(name==null||name.equals("")||password==null||password.equals("")){
baseResp.setCode(123l);
baseResp.setMessage("信息输入不完整!");
return baseResp;
}
User byNameAndPassword = userRepository.findByNameAndPassword(name, password);
if(byNameAndPassword==null){
baseResp.setCode(321l);
baseResp.setMessage("用户信息输入错误,请重新输入!");
return baseResp;
}
Map o = (Map) JSONObject.toJSON(byNameAndPassword);
String token = jwtUtils.token(o);
baseResp.setCode(200l);
baseResp.setMessage(token);
return baseResp;
}
@Override
public BaseResp findTeacher(String token) {
//解析token
Map verify = jwtUtils.Verify(token);
//将map转为object
Object o = JSONObject.toJSON(verify);
//将object转为User
User user = JSONObject.parseObject(o.toString(), User.class);
Integer id = user.getId();
List<TbTeacher> all = teacherClient.findAll();
BaseResp baseResp=new BaseResp();
baseResp.setCode(200l);
baseResp.setMessage(all);
return baseResp;
}
}
4.controller
@RestController
public class UserController {
@Autowired
UserService userService;
@Autowired
JWTUtils jwtUtils;
@RequestMapping("/login")
public BaseResp login(@RequestBody User user){
return userService.findByNameAndPassword(user.getName(),user.getPassword());
}
@RequestMapping("/findAllTeacher")
public BaseResp findAllTeacher(HttpServletRequest request){
Cookie[] cookies = request.getCookies();
String token=null;
if(cookies!=null){
token=getToken(cookies);
}else {
System.out.println("token为null");
}
return userService.findTeacher(token);
}
public String getToken(Cookie[] cookies){
String token=null;
for(Cookie cookie:cookies){
if(cookie.getName().equals("token")){
token= cookie.getValue();
}
}
return token;
}
}
7.utils
7.1pom
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
7.2 JWTUtils
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
8.zuul
8.1pom
<dependency>
<groupId>com.wo</groupId>
<artifactId>live_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.wo</groupId>
<artifactId>live_utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
8.2 bootstrap.yml
server:
port: 7001
spring:
application:
name: live_zuul
cloud:
config:
discovery:
service-id: live_config
enabled: true
name: live-config
profile: dev
#zuul 转发时保留cookie
zuul:
sensitive-headers:
eureka:
client:
service-url:
defaultZone: http://localhost:8888/eureka
8.3 启动类
server:
port: 7001
spring:
application:
name: live_zuul
cloud:
config:
discovery:
service-id: live_config
enabled: true
name: live-config
profile: dev
#zuul 转发时保留cookie
zuul:
sensitive-headers:
eureka:
client:
service-url:
defaultZone: http://localhost:8888/eureka
8.4 AuthorZuulFilter
@Component
public class AuthorZuulFilter extends ZuulFilter{
private static List<String> url = new ArrayList<>();
@Autowired
JWTUtils jwtUtils;
//指定当前过滤器的类型
/*PRE:在请求被路由之前调用,可以使用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试Log等。
*ROUTE:将请求路由到对应的微服务,用于构建发送给微服务的请求。
*POST:在请求被路由到对应的微服务以后执行,可用来为Response添加HTTP Header、将微服务的Response发送给客户端*等。
*ERROR:在其他阶段发生错误时执行该过滤器。
*/
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
//指定过滤器的执行顺序
@Override
public int filterOrder() {
return FilterConstants.PRE_DECORATION_FILTER_ORDER;
}
//配置是否启用
@Override
public boolean shouldFilter() {
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
String requestURI = request.getRequestURI();
if(url.contains(requestURI)){
return false;
}
return true;
}
//指定过滤器中的具体业务代码
@Override
public Object run() throws ZuulException {
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
Cookie[] cookies = request.getCookies();
String token=null;
for(Cookie cook:cookies){
if(cook.getName().equals("token")){
token=cook.getValue();
}
}
Map verify = jwtUtils.Verify(token);
BaseResp baseResp = new BaseResp();
if(verify==null){
currentContext.getResponse().setContentType("application/json;charset=utf-8");
baseResp.setCode(400l);
baseResp.setMessage("用户token验证失败!");
//返回数据到页面
currentContext.setResponseBody(JSONObject.toJSON(baseResp).toString());
//在这里截至不允许继续执行
currentContext.setSendZuulResponse(false);
}
return null;
}
//不拦截的路径
private AuthorZuulFilter(){
url.add("/live-user/login");
url.add("/live-user/registry");
//......
}
}
9.前端页面
9.1 登录VUE
<template>
<div class="hello">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="用户名">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
return {
form:{}
}
},
methods:{
onSubmit:function () {
axios.post("api/live-user/login",this.form).then(res=>{
//登录成功
if (res.data.code==200){
var token = res.data.message;
//将token设置到cookie中
this.$cookie.set("token",token)
this.$router.push("/index")
}else{
alert(res.data.message)
}
})
}
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
9.2主页
<template>
<div>
<template>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="birth" label="生日" width="180"></el-table-column>
<el-table-column prop="score" label="评分"></el-table-column>
</el-table>
</template>
</div>
</template>
<script>
import axios from 'axios'
//设置让axios 携带cookie去请求后端
axios.defaults.withCredentials=true
export default {
name: "",
data(){
return{
tableData:[]
}
},
methods:{
findAll:function () {
axios.get("api/live-user/findAllTeacher").then(res=>{
if (res.data.code==200){
this.tableData=res.data.message
} else{
alert(res.data.message)
this.$router.push("/")
}
})
}
},
mounted(){
this.findAll();
}
}
</script>
<style scoped>
</style>