vue-element-admin 整合 springboot,docker 权限登录功能 框架搭建

搭建一个简单的前后端工程, 前端vue-element-admin ,后端 springboot,数据库postgresql 使用docker打包发布. 功能方面预置登录,账号功能. 方便后续自己添加业务逻辑实现各种管理系统

前端

部署脚本


git fetch --all

git reset --hard origin/dev-prod

npm install

npm run build:prod

chown 1000:1000 -R perftest

echo "start perfTest-vue success!"

echo "restart nginx"

docker restart nginx

echo "restart nginx success"

vue.config.js

 devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    // before: require('./mock/mock-server.js'),
    proxy: {
      '/dev-api': {
        // 目标 API 地址
        target: 'http://localhost:8848', // 开发环境
        ws: true,
        changeOrigin: true,
        pathRewrite: {
          '^/dev-api': '/dev-api' // 这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用'http://40.00.100.100:3002/user/add',直接写‘/api/user/add’即可
        }
      }
    }
  },

后端

部署脚本


git fetch --all

git reset --hard origin/dev_prod

mvn clean package -DskipTests

cp -rf config/ target/

mv target/test-0.0.1-SNAPSHOT.jar target/test.jar

pid=`ps -ef | grep automate_test_pord.jar | grep -v grep | awk '{print $2}'`

kill -9 $pid

echo "pid $pid killed"

nohup java -jar ./target/automate_test_pord.jar  > log_java.log 2>&1 &

echo "star success!"

后端dockerfile


FROM maven:3.8.1-jdk-8 AS MAVEN_BUILD

RUN mkdir -p /build/

COPY src /build/src/

COPY pom.xml /build/

COPY scripts/simpod_docker/settings.xml /etc/maven/setting.xml

WORKDIR /build/



RUN echo "7.223.199.227   mirrors.tools.huawei.com" >> /etc/hosts \

    && mvn clean package --settings /etc/maven/setting.xml



#基于java8

FROM java:8



ENV TZ=Asia/Shanghai

#修改时区

RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \

 && echo 'Asia/Shanghai' >/etc/timezone



#创建一个目录存放jar包

RUN mkdir -p /opt/openstack/



COPY --from=MAVEN_BUILD /build/target/openstack-2.0.jar /opt/openstack/



#添加进入docker容器后的目录

WORKDIR /opt/openstack



#对外暴露的端口号

EXPOSE 8848 20006



#运行脚本,启动springboot项目,这里我们指定加载配置文件的位置,并且通过数据卷挂载同步到容器中

ENTRYPOINT ["java", "-jar", "openstack-2.0.jar", "-Xms4g", "-Xmx4g", "--spring.profiles.active=simpod", "-Dspring.config.location=/opt/openstack/config/application-simpod.yml"]

nginx dockerfile


FROM nginx:stable 



ENV TZ=Asia/Shanghai 

ENV NGINX_PORT=80 



COPY default.conf /etc/nginx/conf.d/default.conf

nginx config


client_max_body_size 1g; 



server { 

  listen 80; 

  root /usr/share/nginx/www; 

  index index.html index.htm; 



  rewrite ^/code /config; 



  location / { 

    proxy_pass  http://grafana:3000/; 



  } 

  location /perftest/ {

    alias /var/lib/perf_autotest_vue/perftest/;

    index index.html;

    try_files $uri $uri/ /perftest/index.html;

  }

  location /prod-api/ {

    proxy_read_timeout 3600; # 秒

    proxy_pass  http://ip:port/prod-api/;

  }

}

后端

common/handle/AuthSuccessHandler


package com.example.demo.handler; 



import com.example.demo.common.R; 

import com.example.demo.mapper.UsrMapper; 

import com.example.demo.model.UsrVo; 

import com.example.demo.util.JwtUtil; 

import com.fasterxml.jackson.databind.ObjectMapper; 



import org.springframework.security.core.Authentication; 

import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; 

import org.springframework.stereotype.Component; 



import java.io.IOException; 

import java.io.PrintWriter; 



import javax.servlet.http.HttpServletRequest; 

import javax.servlet.http.HttpServletResponse; 



import lombok.RequiredArgsConstructor; 



@Component 

@RequiredArgsConstructor 

public class AuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { 



    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); 



    private final UsrMapper usrMapper; 



    @Override 

    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, 

        Authentication authentication) throws 

        IOException { 

        String id = (String) authentication.getPrincipal(); 

        UsrVo usrVo = new UsrVo(usrMapper.selectById(id)); 

        String token = JwtUtil.createToken(usrVo.getId(), usrVo.getRoles()); 

        usrVo.setToken(token); 

        response.setContentType("application/json;charset=utf-8"); 

        PrintWriter writer = response.getWriter(); 

        writer.write(OBJECT_MAPPER.writeValueAsString(R.ok(usrVo))); 

        writer.flush(); 

        writer.close(); 

    }}

common/handle/AuthFailHandler


package com.example.demo.handler; 



import com.example.demo.common.R; 

import com.fasterxml.jackson.databind.ObjectMapper; 



import org.springframework.security.core.AuthenticationException; 

import org.springframework.security.web.authentication.AuthenticationFailureHandler; 

import org.springframework.stereotype.Component; 



import java.io.IOException; 

import java.io.PrintWriter; 



import javax.servlet.ServletException; 

import javax.servlet.http.HttpServletRequest; 

import javax.servlet.http.HttpServletResponse; 



@Component 

public class AuthFailHandler implements AuthenticationFailureHandler { 

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); 



    @Override 

    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, 

        AuthenticationException exception) throws 

        IOException, ServletException { 

        response.setContentType("application/json;charset=utf-8"); 

        PrintWriter writer = response.getWriter(); 

        writer.write(OBJECT_MAPPER.writeValueAsString(R.failed("用户名或密码认证失败,请重试"))); 

        writer.flush(); 

        writer.close(); 

    }}

filter/tokenFilter


package com.example.demo.filter; 



import com.auth0.jwt.interfaces.DecodedJWT; 

import com.example.demo.common.R; 

import com.example.demo.util.JwtUtil; 

import com.fasterxml.jackson.databind.ObjectMapper; 



import org.apache.commons.lang3.StringUtils; 

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 

import org.springframework.security.core.authority.SimpleGrantedAuthority; 

import org.springframework.security.core.context.SecurityContextHolder; 

import org.springframework.stereotype.Component; 

import org.springframework.web.filter.OncePerRequestFilter; 



import java.io.IOException; 

import java.io.PrintWriter; 

import java.util.ArrayList; 

import java.util.List; 



import javax.servlet.FilterChain; 

import javax.servlet.ServletException; 

import javax.servlet.http.HttpServletRequest; 

import javax.servlet.http.HttpServletResponse; 



@Component 

public class TokenFilter extends OncePerRequestFilter { 

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); 



    @Override 

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws 

        ServletException, 

        IOException { 

        String token = request.getHeader("X-Token"); 

        if (StringUtils.isNotBlank(token)) { 

            try { 

                DecodedJWT jwt = JwtUtil.parseToken(token); 

                String userId = jwt.getClaim("userId").asString(); 

                List<String> roles = jwt.getClaim("roles").asList(String.class); 

                List<SimpleGrantedAuthority> authorities = new ArrayList<>(); 

                for (String role : roles) { 

                    authorities.add(new SimpleGrantedAuthority(role)); 

                }                if (null == SecurityContextHolder.getContext().getAuthentication()) { 

                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( 

                        userId, null, authorities); 

                    SecurityContextHolder.getContext().setAuthentication(authenticationToken); 

                }            } catch (Exception e) { 

                response.setContentType("application/json;charset=utf-8"); 

                PrintWriter writer = response.getWriter(); 

                writer.write(OBJECT_MAPPER.writeValueAsString(R.failed("token校验失败,请重试"))); 

                writer.flush(); 

                writer.close(); 

                return; 

            }        }        chain.doFilter(request, response); 

    }}

config/CorsConfig 跨域处理


package com.example.demo.config; 



import org.springframework.context.annotation.Configuration; 

import org.springframework.web.servlet.config.annotation.CorsRegistry; 

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 



@Configuration 

public class CorsConfig implements WebMvcConfigurer { 

  @Override   

public void addCorsMappings(CorsRegistry registry) { 

        registry.addMapping("/**")//项目中的所有接口都支持跨域   

.allowedOriginPatterns("*")//所有地址都可以访问,也可以配置具体地址   

.allowCredentials(true)   

                .allowedMethods("*")//"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"   

.maxAge(3600);// 跨域允许时间   

}   



}

config/SecurityConfiguration


import com.example.demo.filter.TokenFilter; 

import com.example.demo.handler.AuthFailHandler; 

import com.example.demo.handler.AuthSuccessHandler; 



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.EnableWebSecurity; 

import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 

import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 



import lombok.RequiredArgsConstructor; 



/** 

* Author:      wxb * Project:    spring_security_example * Create Date: 2018/10/18 * Create Time: 17:36 * Description: Security 配置类 

*/ 

@EnableWebSecurity 

@RequiredArgsConstructor 

public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 



    private final UserDetailsProvider userDetailsProvider; 

    private final AuthSuccessHandler authSuccessHandler; 

    private final AuthFailHandler authFailHandler; 

    private final TokenFilter tokenFilter; 



    @Override 

    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 

//        auth.userDetailsService(myUserDetailsService).passwordEncoder(new BCryptPasswordEncoder()); 

        // 基于数据库验证 

        auth.authenticationProvider(userDetailsProvider); 

    } 

    @Override 

    protected void configure(HttpSecurity http) throws Exception { 

        http.authorizeRequests() 

              .antMatchers("/**").permitAll()  // 开发时候不做权限校验 

                .antMatchers("/user/*", "/login", "/index", "/static", "/error","/alarm/*").permitAll() 

                .antMatchers("/file/download/*").permitAll() 

                .anyRequest().authenticated() 

                .and() 

                .formLogin() 

//                .loginPage("/login") 

//                .defaultSuccessUrl("/jenkins_job") 

                .usernameParameter("username").passwordParameter("password") 

                .successHandler(authSuccessHandler) 

                .failureHandler(authFailHandler) 

                .and() 

                .csrf().disable() 

                .logout().disable(); 

        http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class); 

    }}

config/UserDetailProvider用户处理类


package com.example.demo.config; 



import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 

import com.example.demo.mapper.UsrMapper; 

import com.example.demo.model.Usr; 



import org.springframework.security.authentication.AuthenticationProvider; 

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 

import org.springframework.security.core.Authentication; 

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 

import org.springframework.stereotype.Component; 



import lombok.RequiredArgsConstructor; 

import lombok.extern.slf4j.Slf4j; 



@Slf4j 

@Component 

@RequiredArgsConstructor 

public class UserDetailsProvider implements AuthenticationProvider { 

    private final UsrMapper usrMapper; 



    @Override 

    public Authentication authenticate(Authentication authentication) { 

        log.info("数据库验证开始"); 

        String username = authentication.getName(); 

        String password = authentication.getCredentials().toString(); 

        LambdaQueryWrapper<Usr> wrapper = new LambdaQueryWrapper<>(); 

        wrapper.eq(Usr::getUsername, username); 

        Usr usr = usrMapper.selectOne(wrapper); 

        if (usr == null) { 

            return null; 

        }        BCryptPasswordEncoder bCryptEncoder = new BCryptPasswordEncoder(); 

        if (bCryptEncoder.matches(password, usr.getPassword())) { 

            log.info("数据库验证通过"); 

            return new UsernamePasswordAuthenticationToken( 

                usr.getId(), password, usr.getAuthorities()); 

        } else { 

            log.info("密码错误,转ldap验证"); 

        }        return null; 

    } 

    @Override 

    public boolean supports(Class<?> authentication) { 

        return authentication.equals( 

            UsernamePasswordAuthenticationToken.class); 

    }}

jwtutil token工具类


package com.example.demo.util; 



import com.auth0.jwt.JWT; 

import com.auth0.jwt.JWTVerifier; 

import com.auth0.jwt.algorithms.Algorithm; 

import com.auth0.jwt.interfaces.DecodedJWT; 



import java.util.Calendar; 

import java.util.Date; 

import java.util.List; 



public class JwtUtil { 

    public static final String SECRET = "PERF_CLOUD_TEST"; 



    public static String createToken(String id, List<String> roles) { 

        Algorithm algorithm = Algorithm.HMAC256(SECRET); 

        Calendar calendar = Calendar.getInstance(); 

        calendar.add(Calendar.HOUR, 12); 

        Date time = calendar.getTime(); 

        return JWT.create() 

            .withIssuer("auth0") 

            .withExpiresAt(time) 

            .withClaim("userId", id) 

            .withClaim("roles", roles) 

            .sign(algorithm); 

    } 

    public static void verifyToken(String token) { 

        Algorithm algorithm = Algorithm.HMAC256(SECRET); 

        JWTVerifier verifier = JWT.require(algorithm) 

            .withIssuer("auth0") 

            .build(); 

        verifier.verify(token); 

    } 

    public static DecodedJWT parseToken(String token) { 

        Algorithm algorithm = Algorithm.HMAC256(SECRET); 

        JWTVerifier verifier = JWT.require(algorithm) 

            .withIssuer("auth0") 

            .build(); 

        return verifier.verify(token); 

    }

}

usrvo类


package com.example.demo.model; 



import java.util.Arrays; 

import java.util.List; 



import lombok.Data; 



@Data 

public class UsrVo { 



    String id; 



    String userName; 



    //    jwt token   

String token; 



    List<String> roles; 



    public UsrVo(Usr usr) { 

        this.id = usr.getId(); 

        this.userName = usr.getUsername(); 

        this.roles = Arrays.asList(usr.getRoles().split(",")); 

    } 

    public UsrVo(Usr usr, String token) { 

        this.id = usr.getId(); 

        this.userName = usr.getUsername(); 

        this.roles = Arrays.asList(usr.getRoles().split(",")); 

        this.token = token; 

    }}

usr类


package com.example.demo.model; 



import com.baomidou.mybatisplus.annotation.TableId; 

import com.fasterxml.jackson.annotation.JsonIgnore; 



import org.springframework.security.core.GrantedAuthority; 

import org.springframework.security.core.authority.SimpleGrantedAuthority; 

import org.springframework.security.core.userdetails.UserDetails; 



import java.util.ArrayList; 

import java.util.Collection; 

import java.util.List; 



import lombok.Data; 



@Data 

public class Usr implements UserDetails { 

    @TableId() 

    String id;   



String userName;   



String cnName;   



String fullName;   



@JsonIgnore 

    String password;   



//    角色  //    @JsonIgnore   

String roles;   





@Override   

public Collection<? extends GrantedAuthority> getAuthorities() { 

        String[] authorities = roles.split(",");   

List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>(); 

        for (String role : authorities) {   

simpleGrantedAuthorities.add(new SimpleGrantedAuthority(role));   

}        return simpleGrantedAuthorities;   

    }   

@Override   

public String getUsername() {   

return userName;   

    }   

@Override   

public boolean isAccountNonExpired() {   

return true;   

    }   

@Override   

public boolean isAccountNonLocked() {   

return true;   

    }   

@Override   

public boolean isCredentialsNonExpired() {   

return true;   

    }   

@Override   

public boolean isEnabled() {   

return true;   

    }}

usrmapper


@Mapper 

package com.example.demo.mapper; 



import com.baomidou.mybatisplus.core.mapper.BaseMapper; 

import com.example.demo.model.Usr; 



import org.apache.ibatis.annotations.Mapper; 



@Mapper 

public interface UsrMapper extends BaseMapper<Usr> { 

}

通用response


package com.example.demo.common; 



import java.io.Serializable; 



import lombok.AllArgsConstructor; 

import lombok.Data; 

import lombok.NoArgsConstructor; 

import lombok.ToString; 

import lombok.experimental.Accessors; 



@Data 

@ToString 

@NoArgsConstructor 

@AllArgsConstructor 

@Accessors(chain = true) 

public class R<T> implements Serializable { 



    private static final long serialVersionUID = 1L; 



    private int code; 



    private String msg; 



    private T data; 



    private static Integer SUCCESS = 0; 

    private static Integer FAIL = 1; 



    public static <T> R<T> ok() { 

        return restResult(null, SUCCESS, null); 

    } 

    public static <T> R<T> ok(T data) { 

        return restResult(data, SUCCESS, null); 

    } 

    public static <T> R<T> ok(T data, String msg) { 

        return restResult(data, SUCCESS, msg); 

    } 

    public static <T> R<T> failed() { 

        return restResult(null, FAIL, null); 

    } 

    public static <T> R<T> failed(String msg) { 

        return restResult(null, FAIL, msg); 

    } 

    public static <T> R<T> failed(T data) { 

        return restResult(data, FAIL, null); 

    } 

    public static <T> R<T> failed(T data, String msg) { 

        return restResult(data, FAIL, msg); 

    } 

    private static <T> R<T> restResult(T data, int code, String msg) { 

        R<T> apiResult = new R<>(); 

        apiResult.setCode(code); 

        apiResult.setData(data); 

        apiResult.setMsg(msg); 

        return apiResult; 

    }}

application.yml


spring: 

  datasource: 

    url: jdbc:postgresql://xxx.xxx.xxx.xxx:xxx/postgres

    username: username 

    password: password 

    driver-class-name: org.postgresql.Driver

pom.xml


<dependencies> 

  <dependency> 

      <groupId>org.springframework.boot</groupId> 

      <artifactId>spring-boot-starter-security</artifactId> 

  </dependency> 

  <dependency> 

      <groupId>org.springframework.boot</groupId> 

      <artifactId>spring-boot-starter-web</artifactId> 

  </dependency> 

  <dependency> 

      <groupId>org.postgresql</groupId> 

      <artifactId>postgresql</artifactId> 

      <scope>runtime</scope> 

  </dependency> 



  <dependency> 

      <groupId>org.projectlombok</groupId> 

      <artifactId>lombok</artifactId> 

      <optional>true</optional> 

  </dependency> 

  <dependency> 

      <groupId>org.apache.commons</groupId> 

      <artifactId>commons-lang3</artifactId> 

  </dependency> 

  <dependency> 

      <groupId>com.alibaba</groupId> 

      <artifactId>fastjson</artifactId> 

      <version>1.2.80</version> 

  </dependency> 

  <dependency> 

      <groupId>com.auth0</groupId> 

      <artifactId>java-jwt</artifactId> 

      <version>4.2.1</version> 

  </dependency> 

  <dependency> 

      <groupId>com.baomidou</groupId> 

      <artifactId>mybatis-plus-boot-starter</artifactId> 

      <version>3.5.1</version> 

  </dependency> 

  <dependency> 

      <groupId>org.springframework.boot</groupId> 

      <artifactId>spring-boot-devtools</artifactId> 

      <scope>runtime</scope> 

      <optional>true</optional> 

  </dependency> 

  <dependency> 

      <groupId>org.springframework.boot</groupId> 

      <artifactId>spring-boot-starter-test</artifactId> 

      <scope>test</scope> 

  </dependency> 

  <dependency> 

      <groupId>org.springframework.security</groupId> 

      <artifactId>spring-security-test</artifactId> 

      <scope>test</scope> 

  </dependency> 

</dependencies>

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容