Vue 3에서 토큰 인증 처리
7608 단어 authenticationvuewebdevsecurity
나는 이것이 내가 배운 지식을 공유하는 좋은 장소일 수도 있고, 내 관중들이 내가 하고 있는 일에 대해 코드 심사를 할 수도 있다고 생각한다.도와줘서 고마워요!
학습을 계속하려면 다음 예제를 참조하십시오.
최소 ASP.NET Core 프로젝트는 두 개의 API를 공개했습니다(하나는 인증용, 다른 하나는 색조 반환용).인증을 수행하면 JWT만 반환됩니다.
[HttpPost]
public ActionResult<AuthResultModel> Post([FromBody] AuthRequestModel model)
{
// NEVER DO THIS, JUST SHOWING THE EXAMPLE
if (model.Username == "[email protected]"
&& model.Password == "P@ssw0rd!")
{
var result = new AuthResultModel()
{
Success = true
};
// Never do this either, hardcoded strings
var token = TokenSecurity.GenerateJwt(model.Username);
result.Token = new JwtSecurityTokenHandler().WriteToken(token);
result.Expiration = token.ValidTo;
return Created("", result);
}
return BadRequest("Unknown failure");
}
Vue 섹션의 최소 JWT 구현을 테스트할 뿐이므로 서버 코드를 예로 사용하지 마십시오.클라이언트 디렉토리에 Vue 3 항목이 있습니다.이것이 바로 우리가 주목해야 할 곳이다.우선 로그인 페이지가 필요합니다.
<template>
<div>
<h1>Login</h1>
<form novalidate @submit.prevent="onSubmit()">
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" v-model="model.username" class="form-control" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" v-model="model.password" class="form-control" />
</div>
<div class="form-group">
<input type="submit" class="btn btn-success" value="Login" />
<router-link class="btn btn-info" to="/">Cancel</router-link>
</div>
</form>
</div>
</template>
<script>
import { reactive } from "vue";
import store from "@/store";
export default {
setup() {
const model = reactive({ username: "", password: ""});
function onSubmit() {
store.dispatch("login", model);
}
return {
model,
onSubmit
}
}
}
</script>
이 모든 것은 우리의 모델을 채택하고 이를 Vuex에 보내서 실제 인증을 하는 것입니다.이것은 단지 간단한 형식일 뿐이다.모든 진정한 마법은 Vuex 상점에 있습니다.actions: {
login: async ({ commit }, model) => {
try {
commit("setBusy");
commit("clearError");
const http = createHttp(false); // unsecured
const result = await http.post("/api/auth", model);
if (result.data.success) {
commit("setToken", result.data);
router.push("/");
}
else {
commit("setError", "Authentication Failed");
}
} catch {
commit("setError", "Failed to login");
} finally {
commit("clearBusy");
}
},
}
이 동작에서, 나는 단지post와 사용자 이름/비밀번호로 서비스를 호출할 뿐이다.만약 성공한다면, 나는 영패를 저장할 것이다. (Vuex에도 저장할 것이다.)토큰의 실제 저장, 토큰, 만료 설정: mutations: {
// ...
setToken: (state, model) => {
state.token = model.token;
state.expiration = new Date(model.expiration)
}
},
그리고 getter가 로그인 여부를 되돌려줍니다. getters: {
isAuthenticated: (state) => {
return state.token.length > 0 &&
state.expiration > Date.now();
}
},
getter는 우리가 영패가 있는지, 기한이 지났는지 테스트하고 있습니다.만기가 다가오면서 다시 로그인할 수 있는 신기한 방법은 없다.Vuex 객체에 자격 증명을 저장하여 재검증하지 않는 것이 좋습니다. 이는 상당한 보안 취약점입니다.다음 사용자가 필요할 때, 나는 로그인 페이지로 방향을 바꿀 뿐이다.그러나 이 가설은 사실상 당신의 특정한 용례를 바탕으로 한다.서버에서 인증된 호출마다 만료 시간을 미끄러뜨릴 수 있지만 보안이 높은 상황에서 사용해서는 안 됩니다.지금 우리는 로그인하는 방법이 생겼는데, 우리는 어떻게 해야 합니까?이것이 바로 루트의 용무지이다.다음과 같은 간단한 라우팅 세 페이지(로그인 포함)가 있습니다.
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/colors',
name: 'Colors',
component: Colors,
},
{
path: '/login',
name: 'Login',
component: Login
},
]
그러나 일부 페이지가 인증되지 않으면 보호해 주십시오.우리가 이 점을 할 수 있는 것은 마치 수비수와 같다.보호는 루트 파이프 기간에 실행되는 작은 코드입니다.예를 들어, 라우팅을 실행하기 전에 라우팅을 실행하고자 합니다.const authGuard = (to, from, next) => {
if (store.getters.isAuthenticated) {
next();
} else {
next("/login")
}
};
이 방법은 루트의 목적지, 출처, 그리고 최종 호출된 함수 (next) 를 가져와 루트를 호출하거나 다시 호출합니다.우리의 예에서, 만약 그것이 신분 검증을 거쳤다면, 우리는 다음 것을 호출하여 원하는 곳으로 이동할 수 있을 뿐이다.그러나 그렇지 않으면 로그인 페이지로 다시 지정합니다.일단 우리가 이 함수를 가지게 되면 우리는 그것을 필요한 경로에 적용할 수 있다. {
path: '/colors',
name: 'Colors',
component: Colors,
beforeEnter: authGuard
},
이렇게 하면 인증 전에 "색상"을 입력하면 로그인 페이지로 다시 라우팅됩니다.이 예는 로그인 후 색을 바꾸는 문제를 처리하지 않았지만, 쉽게 할 수 있습니다.제 예에서는 로그인할 때마다 Vue 프로젝트의 루트로 리디렉션합니다.const result = await http.post("/api/auth", model);
if (result.data.success) {
commit("setToken", result.data);
router.push("/");
}
router.push("/")>
에 대한 호출은 방향을 바꾸는 작용이다.알겠습니다. 로그인하지 않은 사람이 방문하지 않도록 경로가 보호되었습니다. 하지만 지금 우리는 JWT 영패를 어떻게 사용합니까?이 예에서, 나는axios를 네트워크에 사용할 것입니다. (그러나fetch를 사용하여 유사한 작업을 할 수 있습니다.)이 예에서 나는 내가 사용하는 http 대상을 구축하는 함수를 가지고 있다.
import axios from "axios";
import store from "@/store";
export default function createHttp(secured = true) {
if (secured) {
return axios.create({
headers: { "Authorization": `bearer ${store.state.token}` }
});
} else {
return axios.create();
}
}
createHttp를 호출할 때 매개 변수 (또는true) 가 없으면 저장소에서 권한 부여 헤더를 자동으로 추가합니다.그렇지 않으면, 나는 하나만 만들 것이다.왜 우리 둘 다 필요해?응, 안전하지 않은 것은 사실상 로그인에 필요한 거야.이것이 바로 기본 설정이 보안 연결을 만드는 이유입니다.이 최소한의 예시가 당신의 Vue 프로젝트에서 영패를 사용할 수 있기를 바랍니다.만약 당신이 개선 예시를 보았다면 저에게 (또는 직접 저에게 PR을 주세요.)
Shawn Wildermuth의 이 작품은 Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License에 따라 허가를 받았다.
wildermuth.com 기반 작업.
이 글을 좋아하신다면 Shawn 강의 Pluralsight 를 참조하십시오.
Reference
이 문제에 관하여(Vue 3에서 토큰 인증 처리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/shawnwildermuth/handling-token-authentication-in-vue-3-1i5k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)