vue前端img訪問鑒權(quán)后端進(jìn)行攔截的代碼示例
前言
此文章為了解決匿名可以訪問圖片問題,有的文章是重構(gòu)了el-img組件,使用blob重新進(jìn)行加載。該文章是換個(gè)思路,在圖片訪問地址后面追加token參數(shù),后端進(jìn)行攔截,判斷token是否有效,無效則攔截。反之通過。同時(shí)會(huì)校驗(yàn)是否同一臺(tái)電腦、同一瀏覽器、同一操作系統(tǒng)、同一登錄地點(diǎn)
前端:
image-preview組件:
<template> <el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList" append-to-body="true" > <template #error> <div class="image-slot"> <el-icon><picture-filled /></el-icon> </div> </template> </el-image> </template> <script setup> import { isExternal } from "@/utils/validate"; import { getToken } from "@/utils/auth"; import {watch} from "vue"; const tokenInfo = ref(getToken()) const props = defineProps({ src: { type: String, required: true }, srcViewerList: { type: Array }, width: { type: [Number, String], default: "" }, height: { type: [Number, String], default: "" } }); const realSrc = computed(() => { let real_src = props.src.split(",")[0]; if (isExternal(real_src)) { return real_src; } return import.meta.env.VITE_APP_BASE_API + real_src + '?token=' + tokenInfo.value; }); const realSrcList = ref([]); watch(() => { props.srcViewerList.forEach(item => { realSrcList.value.push(item + '?token=' + tokenInfo.value) }); }) // const realSrcList = computed(() => { // let real_src_list = props.src.split(","); // let srcList = []; // real_src_list.forEach(item => { // if (isExternal(item)) { // return srcList.push(item); // } // return srcList.push(import.meta.env.VITE_APP_BASE_API + item + '?token=' + tokenInfo.value); // }); // return srcList; // }); const realWidth = computed(() => typeof props.width == "string" ? props.width : `${props.width}px` ); const realHeight = computed(() => typeof props.height == "string" ? props.height : `${props.height}px` ); </script> <style lang="scss" scoped> .el-image { border-radius: 5px; background-color: #ebeef5; box-shadow: 0 0 5px 1px #ccc; :deep(.el-image__inner) { transition: all 0.3s; cursor: pointer; &:hover { transform: scale(1.2); } } :deep(.image-slot) { display: flex; justify-content: center; align-items: center; width: 100%; height: 100%; color: #909399; font-size: 30px; } } </style>
后端攔截器:
ProfileInterceptorConfig.java
package com.fuel.framework.config; import com.fuel.framework.interceptor.ProfileInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 通用配置 * * @author hhxx */ @Configuration public class ProfileInterceptorConfig implements WebMvcConfigurer { @Autowired private ProfileInterceptor profileInterceptor; /** * 自定義攔截規(guī)則 */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(profileInterceptor) .addPathPatterns("/profile/**"); } }
ProfileInterceptor.java
package com.fuel.framework.interceptor; import com.alibaba.fastjson2.JSON; import com.fuel.common.constant.HttpStatus; import com.fuel.common.core.domain.AjaxResult; import com.fuel.common.core.domain.model.LoginUser; import com.fuel.common.utils.ServletUtils; import com.fuel.common.utils.StringUtils; import com.fuel.common.utils.ip.AddressUtils; import com.fuel.common.utils.ip.IpUtils; import com.fuel.common.utils.spring.SpringUtils; import com.fuel.framework.security.handle.AuthenticationEntryPointImpl; import com.fuel.framework.web.service.TokenService; import eu.bitwalker.useragentutils.UserAgent; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; @Component public class ProfileInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //獲取token String token = request.getParameter("token"); // 獲取用戶代理 UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); // 獲取ip String ipaddr = IpUtils.getIpAddr(ServletUtils.getRequest()); // 獲取登錄地點(diǎn) String loginLocation = AddressUtils.getRealAddressByIP(ipaddr); // 獲取瀏覽器 String browser = userAgent.getBrowser().getName(); // 獲取操作系統(tǒng) String os = userAgent.getOperatingSystem().getName(); TokenService bean = SpringUtils.getBean(TokenService.class); AuthenticationEntryPointImpl authenticationEntryPointImpl = SpringUtils.getBean(AuthenticationEntryPointImpl.class); // 校驗(yàn)token是否有效 Map<String, Object> stringObjectMap = bean.verifyToken(token); boolean bl = false; if (stringObjectMap.size() > 0) { // 獲取登錄信息 LoginUser user = (LoginUser) stringObjectMap.get("user"); // 判斷是否同一臺(tái)電腦、同一瀏覽器、同一操作系統(tǒng)、同一登錄地點(diǎn) if (user != null && ipaddr.equals(user.getIpaddr()) && loginLocation.equals(user.getLoginLocation()) && browser.equals(user.getBrowser()) && os.equals(user.getOs())) { bl = true; } } if(!bl){ // 校驗(yàn)不通過時(shí)返回錯(cuò)誤信息--復(fù)用Spring Security框架的信息 authenticationEntryPointImpl.commence(request, response, null); } return bl; } }
TokenService.java
package com.fuel.framework.web.service; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.auth0.jwt.exceptions.JWTVerificationException; import com.auth0.jwt.exceptions.TokenExpiredException; import com.fuel.common.constant.Constants; import com.fuel.common.core.domain.AjaxResult; import com.fuel.common.core.domain.model.LoginUser; import com.fuel.common.core.redis.RedisCache; import com.fuel.common.utils.MessageUtils; import com.fuel.common.utils.ServletUtils; import com.fuel.common.utils.StringUtils; import com.fuel.common.utils.http.HttpUtils; import com.fuel.common.utils.ip.AddressUtils; import com.fuel.common.utils.ip.IpUtils; import com.fuel.common.utils.uuid.IdUtils; import eu.bitwalker.useragentutils.UserAgent; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; /** * token驗(yàn)證處理 * * @author hhxx */ @Component public class TokenService { // 令牌自定義標(biāo)識(shí) @Value("${token.header}") private String header; // 令牌秘鑰 @Value("${token.secret}") private String secret; // 令牌有效期(默認(rèn)30分鐘) @Value("${token.expireTime}") private int expireTime; protected static final long MILLIS_SECOND = 1000; protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; @Autowired private RedisCache redisCache; /*** * 驗(yàn)證令牌 * @param token * @return */ public Map<String,Object> verifyToken(String token) { Map<String,Object> resultMap = new HashMap<>(); boolean bl = true; try { Claims claims = parseToken(token); // 解析對應(yīng)的權(quán)限以及用戶信息 String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); String userKey = getTokenKey(uuid); LoginUser user = JSONObject.parseObject(redisCache.getCacheObject(userKey),LoginUser.class); if(user != null) { bl = true; resultMap.put("bl", bl); }else { bl = false; resultMap.put("bl", bl); resultMap.put("msg", "token已過期"); } }catch (ExpiredJwtException eje) { bl = false; resultMap.put("bl", bl); resultMap.put("msg", "token已過期"); } catch(Exception ex) { bl = false; resultMap.put("bl", bl); resultMap.put("msg", "token驗(yàn)證異常"); } return resultMap; } }
總結(jié)
到此這篇關(guān)于vue前端img訪問鑒權(quán)后端進(jìn)行攔截的文章就介紹到這了,更多相關(guān)vue前端img訪問鑒權(quán)后端攔截內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue安裝node-sass和sass-loader報(bào)錯(cuò)問題的解決辦法
這篇文章主要給大家介紹了關(guān)于vue安裝node-sass和sass-loader報(bào)錯(cuò)問題的解決辦法,文中通過圖文以及示例代碼將解決的方法介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-01-01uniapp+vue3路由跳轉(zhuǎn)傳參的實(shí)現(xiàn)
本文主要介紹了uniapp+vue3路由跳轉(zhuǎn)傳參的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11vue 實(shí)現(xiàn)基礎(chǔ)組件的自動(dòng)化全局注冊
這篇文章主要介紹了vue 實(shí)現(xiàn)基礎(chǔ)組件的自動(dòng)化全局注冊的方法,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12iview的table組件自帶的過濾器實(shí)現(xiàn)
這篇文章主要介紹了iview的table組件自帶的過濾器實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Element?UI?table參數(shù)中的selectable的使用及遇到坑
這篇文章主要介紹了Element?UI?table參數(shù)中的selectable的使用及遇到的坑,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08Vue報(bào)錯(cuò):TypeError:?Cannot?create?property?‘xxxx‘?on的解決
這篇文章主要介紹了Vue報(bào)錯(cuò):TypeError:?Cannot?create?property?‘xxxx‘?on的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06vue實(shí)現(xiàn)點(diǎn)擊按鈕“查看詳情”彈窗展示詳情列表操作
這篇文章主要介紹了vue實(shí)現(xiàn)點(diǎn)擊按鈕“查看詳情”彈窗展示詳情列表操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09vue在標(biāo)簽中如何使用(data-XXX)自定義屬性并獲取
這篇文章主要介紹了vue在標(biāo)簽中如何使用(data-XXX)自定義屬性并獲取,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08