最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue2+springsecurity權(quán)限系統(tǒng)的實(shí)現(xiàn)

 更新時(shí)間:2023年05月04日 11:17:08   作者:用戶6125466032139  
本文主要介紹了vue2+springsecurity權(quán)限系統(tǒng)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

準(zhǔn)備內(nèi)容

新建項(xiàng)目,SpringBoot采用2.7.11,spring-boot-starter-security,vue 2.0

默認(rèn)會(huì)自動(dòng)啟動(dòng)攔截裝置,可以這樣取消,先這樣配置一下

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})

JWT 校驗(yàn)用戶的憑證(頭部,載荷,簽證)

引入依賴

<!-- JWT -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.2.0</version>
</dependency>

邏輯:用戶登錄后,請(qǐng)求頭中加一個(gè)token參數(shù),如果有則表示可以訪問(wèn),沒(méi)有就不能訪問(wèn),這是一個(gè)小測(cè)試還是有點(diǎn)缺陷的

SpringSecurity 權(quán)限控制

一共有兩個(gè)最主要攔截器

  • 登陸驗(yàn)證攔截器AuthenticationProcessingFilter

  • 資源管理攔截器AbstractSecurityInterceptor

但攔截器里面的實(shí)現(xiàn)需要一些組件來(lái)實(shí)現(xiàn)分別是

  • AuthenticationManager認(rèn)證管理器

  • accessDecisionManager決策管理器等組件來(lái)支撐。

流程圖解讀:

  • 用戶提交用戶名、密碼被SecurityFilterChain中的 UsernamePasswordAuthenticationFilter 過(guò)濾器獲取到,封裝為請(qǐng)求Authentication,通常情況下是UsernamePasswordAuthenticationToken這個(gè)實(shí) 現(xiàn)類。

  • 然后過(guò)濾器將Authentication提交至認(rèn)證管理器(AuthenticationManager)進(jìn)行認(rèn)證 。

  • 認(rèn)證成功后, AuthenticationManager 身份管理器返回一個(gè)被填充滿了信息的(包括上面提到的權(quán) 限信息, 身份信息,細(xì)節(jié)信息,但密碼通常會(huì)被移除) Authentication 實(shí)例。

  • SecurityContextHolder 安全上下文容器將第3步填充了信息的 Authentication
    通過(guò) SecurityContextHolder.getContext().setAuthentication(…)方法,設(shè)置到其中。 可以看出 AuthenticationManager接口(認(rèn)證管理器)是認(rèn)證相關(guān)的核心接口,也是發(fā)起認(rèn)證的出發(fā)點(diǎn),它的實(shí) 現(xiàn)類為ProviderManager。而Spring Security支持多種認(rèn)證方式,因此ProviderManager維護(hù)著一個(gè) List 列表,存放多種認(rèn)證方式,最終實(shí)際的認(rèn)證工作是由 AuthenticationProvider完成的。咱們知道 web表單的對(duì)應(yīng)的AuthenticationProvider實(shí)現(xiàn)類為 DaoAuthenticationProvider,它的內(nèi)部又維護(hù)著 一個(gè)UserDetailsService負(fù)責(zé)UserDetails的獲取。最終 AuthenticationProvider將UserDetails填充至 Authentication。

現(xiàn)在關(guān)掉之前的SecurityAutoConfiguration.class,打開(kāi)是不是直接跳轉(zhuǎn)到了登錄頁(yè)面呢,無(wú)法訪問(wèn)接口了

配置 SpringSecurity

先說(shuō)下創(chuàng)建token的工具類

/**
 * 簽發(fā)JWT
 *
 * @param id 用戶ID
 * @param subject   可以是JSON數(shù)據(jù) 盡可能少
 * @param ttlMillis 不知道
 * @return 結(jié)果
 */
public static String createJWT(String id, String subject, long ttlMillis) {
    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
    // 獲取當(dāng)前時(shí)間毫秒
    long nowMillis = System.currentTimeMillis();
    // 獲取當(dāng)前時(shí)間日期類型
    Date now = new Date(nowMillis);
    // 生成一個(gè)加密的key
    SecretKey secretKey = generalKey();
    JwtBuilder builder = Jwts.builder()
            .setId(id)
            .setSubject(subject)   // 主題
            .setIssuer("ChiHaiKeJi2016")     // 簽發(fā)者
            .setIssuedAt(now)   // 簽發(fā)時(shí)間
            .signWith(signatureAlgorithm, secretKey); // 簽名算法以及密匙
    if (ttlMillis >= 0) {
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        builder.setExpiration(expDate); // 過(guò)期時(shí)間
    }
    return builder.compact();
}
/**
 * 生成jwt token
 * @param username 用戶名
 */
public static String genJwtToken(String username) {
    return createJWT(username, username, 60 * 60 * 1000);
}
/**
 * 生成加密Key
 */
public static SecretKey generalKey() {
    // 目前只知道這個(gè)方法生成一個(gè)key,并用base64解碼
    byte[] encodedKey = Base64.decode(JwtConstant.JWT_SECERT);
    // 目前不知道啥意思
    return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
}

配置信息--新建SecurityConfig

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
    // 白名單
    private static final String[] URL_WHITE_LIST = {"/login"};
    @Resource
    private LoginHandler loginHandler;
    // 密碼加密方式
    @Bean
    protected PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        // 開(kāi)啟跨域 以及csrf攻擊關(guān)閉
        httpSecurity.cors().and().csrf().disable()
                // 登錄登出配置
                .formLogin()
                // 登錄成功接口
                .successHandler(loginHandler)
                // 登錄失敗的接口
                .failureHandler(loginHandler)
//                .and().logout().logoutSuccessHandler()
                // session禁用配置
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 無(wú)狀態(tài),前后端分離
                // 攔截規(guī)則配置 // // 白名單內(nèi)容放行
                .and().authorizeRequests().antMatchers(URL_WHITE_LIST).permitAll()
                // 需要認(rèn)證
                .anyRequest().authenticated();
        return httpSecurity.build();
    }
}

配置登錄失敗與成功接口---新建---LoginHandler 處理類

/**
 * 登錄成功與失敗處理器
 */
@Component
public class LoginHandler implements AuthenticationSuccessHandler, AuthenticationFailureHandler {
    // 登錄成功的
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream stream = response.getOutputStream();
        // 獲取token
        String token = JwtUtils.genJwtToken("user");
        // 寫入數(shù)據(jù)
        stream.write(JSONUtil.toJsonStr(new Result("登錄成功", token)).getBytes());
        stream.flush();
        stream.close();
    }
    // 登錄失敗的
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream stream = response.getOutputStream();
        String message = exception.getMessage();
        if (exception instanceof BadCredentialsException) {
            message = "用戶名或者密碼錯(cuò)誤!";
        }
        stream.write(JSONUtil.toJsonStr(new Result(message)).getBytes(StandardCharsets.UTF_8));
        stream.flush();
        stream.close();
    }
}

在用戶service實(shí)現(xiàn)類中自定義查詢數(shù)據(jù)庫(kù)

@Service
public class SysUserServiceImpl implements SysUserService, UserDetailsService {
    @Resource
    private SysUserMapper sysUserMapper;
    // 自定義查詢參數(shù)是用戶名
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<SysUser> sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserLambdaQueryWrapper.eq(SysUser::getUsername, username);
        SysUser user = sysUserMapper.selectOne(sysUserLambdaQueryWrapper);
        if (user == null) {
            throw new UsernameNotFoundException("用戶名或密碼錯(cuò)誤!");
        } else if ("1".equals(user.getStatus())) {
            throw new UsernameNotFoundException("該用戶已被封禁!");
        }
        // 第三個(gè)是擁有權(quán)限
        return new User(user.getUsername(), user.getPassword(), getUserAuthority());
    }
    // 權(quán)限
    private List<GrantedAuthority> getUserAuthority() {
        return new ArrayList<>();
    }
}

再來(lái)說(shuō)下前端,先配置跨域

module.exports = {
  devServer: {
    host: '0.0.0.0', // 可以忽略不寫
    port: 8080, // 它是用來(lái)修改你打開(kāi)后的端口號(hào)的
    open: true, // 值為 true的話,項(xiàng)目啟動(dòng)時(shí)自動(dòng)打開(kāi)到瀏覽器里邊, false不會(huì)打開(kāi)
    proxy: {
      '/api': {
        target: 'http://localhost:82', // 跨域請(qǐng)求的公共地址
        ws: false, // 也可以忽略不寫,不寫不會(huì)影響跨域
        changeOrigin: true, // 是否開(kāi)啟跨域,值為 true 就是開(kāi)啟, false 不開(kāi)啟
        pathRewrite: {
          '^/api': ''// 注冊(cè)全局路徑, 但是在你請(qǐng)求的時(shí)候前面需要加上 /api
        }
      }
    }
  }
}

配置axios,因?yàn)榕渲昧丝缬?,這個(gè)時(shí)候可以直接寫api了

import axios from 'axios'
const request = axios.create({
  baseURL: '/api' // 因?yàn)榕渲每缬蛄?
})
// 下面這是攔截器,攔截請(qǐng)求,自動(dòng)加token令牌
request.interceptors.request.use(
  config => {
    config.headers.token = `${localStorage.getItem('token')}`
    return config
  }
)
export default request

說(shuō)下如何請(qǐng)求前端登錄接口POST請(qǐng)求
    登錄接口就是login,傳入username和password就可以了

export const Login = function (data) {
  return request({
    method: 'post',
    url: 'login',
    data: qs.stringify(data)
  })
}

到此這篇關(guān)于vue2+springsecurity權(quán)限系統(tǒng)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)vue springsecurity權(quán)限內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue keep-alive中的生命周期解讀

    vue keep-alive中的生命周期解讀

    這篇文章主要介紹了vue keep-alive中的生命周期,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 關(guān)于vuepress部署出現(xiàn)樣式的問(wèn)題及解決

    關(guān)于vuepress部署出現(xiàn)樣式的問(wèn)題及解決

    這篇文章主要介紹了關(guān)于vuepress部署出現(xiàn)樣式的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 快速了解vue-cli 3.0 新特性

    快速了解vue-cli 3.0 新特性

    vue-cli 是 vue 官方團(tuán)隊(duì)推出的一款快速開(kāi)發(fā) vue 項(xiàng)目的構(gòu)建工具,具有開(kāi)箱即用并且提供簡(jiǎn)潔的自定義配置等功能。這篇文章主要介紹了快速了解vue-cli 3.0 新特性,需要的朋友可以參考下
    2018-02-02
  • 詳解element-ui中form驗(yàn)證雜記

    詳解element-ui中form驗(yàn)證雜記

    這篇文章主要介紹了詳解element-ui中form驗(yàn)證雜記,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • vue頁(yè)面使用阿里oss上傳功能的實(shí)例(二)

    vue頁(yè)面使用阿里oss上傳功能的實(shí)例(二)

    本篇文章主要介紹了vue頁(yè)面使用阿里oss上傳功能的實(shí)例(二),主要介紹OSS管理控制臺(tái)設(shè)置訪問(wèn)權(quán)限、角色等,有興趣的可以了解一下
    2017-08-08
  • element-ui中導(dǎo)航組件menu的一個(gè)屬性:default-active說(shuō)明

    element-ui中導(dǎo)航組件menu的一個(gè)屬性:default-active說(shuō)明

    這篇文章主要介紹了element-ui中導(dǎo)航組件menu的一個(gè)屬性:default-active說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • vue3+ts+vite使用el-table表格渲染記錄重復(fù)情況

    vue3+ts+vite使用el-table表格渲染記錄重復(fù)情況

    這篇文章主要給大家介紹了關(guān)于vue3+ts+vite使用el-table表格渲染記錄重復(fù)情況的相關(guān)資料,我們可以通過(guò)合并渲染、數(shù)據(jù)緩存或虛擬化等技術(shù)來(lái)減少重復(fù)渲染的次數(shù),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • 詳解vue+webpack+express中間件接口使用

    詳解vue+webpack+express中間件接口使用

    這篇文章主要介紹了詳解vue+webpack+express中間件接口使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • vue2封裝webSocket的實(shí)現(xiàn)(開(kāi)箱即用)

    vue2封裝webSocket的實(shí)現(xiàn)(開(kāi)箱即用)

    在Vue2中,可以使用WebSocket實(shí)時(shí)通信,本文主要介紹了vue2封裝webSocket的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Vue3中使用Element-Plus的el-upload組件限制只上傳一個(gè)文件的功能實(shí)現(xiàn)

    Vue3中使用Element-Plus的el-upload組件限制只上傳一個(gè)文件的功能實(shí)現(xiàn)

    在 Vue 3 中使用 Element-Plus 的 el-upload 組件進(jìn)行文件上傳時(shí),有時(shí)候需要限制只能上傳一個(gè)文件,本文將介紹如何通過(guò)配置 el-upload 組件實(shí)現(xiàn)這個(gè)功能,讓你的文件上傳變得更加簡(jiǎn)潔和易用,需要的朋友可以參考下
    2023-10-10

最新評(píng)論

江城| 台州市| 湄潭县| 姜堰市| 龙口市| 武鸣县| 义乌市| 潜山县| 神农架林区| 盘锦市| 永善县| 南木林县| 平谷区| 叙永县| 蓬溪县| 石渠县| 浑源县| 河源市| 博白县| 长兴县| 天峻县| 灵山县| 和顺县| 苏尼特右旗| 穆棱市| 十堰市| 军事| 上高县| 洛南县| 呼伦贝尔市| 库伦旗| 盐津县| 郯城县| 阳谷县| 绍兴县| 天柱县| 博客| 华蓥市| 南木林县| 治多县| 镇巴县|