One week review


Hello , Another Monday full of energy , See you again , The weekend is reunion day , It's just that the front and back of us are reunited , Why do you say that , Because the future development may need to be the front and back end together , The two sides finally joined hands , A few days to go Vue The series is basically over , Let's cheer on duck , What about today's content , In fact, you should be able to guess the title carefully , The premise is that you've been watching this series , Including before .net
core part , Here's a brief introduction to what we said last week :

Monday :《 nineteen ║Vue Basics : Style dynamic binding + life cycle
<https://www.cnblogs.com/laozhang-is-phi/p/9611632.html>》 The key points are as follows Vue Eight life cycles in development
, This is a key point , I hope you can have a look , This will be often encountered in future development ;

Tuesday :《 twenty ║Vue Basic final : Detailed explanation of components + Project description
<https://www.cnblogs.com/laozhang-is-phi/p/9622031.html>》 It focuses on the following components
Use of , Including definitions , Transmission value , Use, etc , This is the top priority , The use of components in Vue Is essential in the development of ;

Wednesday :《 twenty-one ║Vue actual combat : Construction of development environment 【 Detailed Edition 】
<https://www.cnblogs.com/laozhang-is-phi/p/9629026.html>》 The development environment is described in detail
Construction of , It's not just about how to build it , Each tool is also described in detail , The significance of plug-in ;

Thursday :《 docosa- ║Vue actual combat : Personal blog first edition (axios+router)
<https://www.cnblogs.com/laozhang-is-phi/p/9640974.html>
》 According to the environment set up on Wednesday , For the first time, we created our first personal blog , Packaged axios , It's the first time we're connected to the one before us .net core api;

Friday :《 tricosa- ║Vue actual combat :Vuex It's very simple
<https://www.cnblogs.com/laozhang-is-phi/p/9647008.html>》 Through a small DEMO It explains Vuex
How is it done to us Vue Implementing state management , Let everyone have a certain understanding of its use , To lay the foundation for the use in future large projects ;

On Friday , Let's go through the Componentization of forms , To explain vuex The significance of existence , We'll still use this today vuex , And it will cooperate .net core
api, What is it ? Look at today's presentation .

be careful : On Thursday , I only wrote the front page of my personal blog , On the weekend , The details page has been updated , You can go by yourself Git see , There is an address at the end of the text

 

 

Zero , We're going to finish the pink block in the lower right corner today

 

 

One , How to realize the process of authority verification

You must remember that before .net core api In the series 《 Frame 5 || Swagger Use of 3.3 JWT Authority verification 【 modify 】
<https://www.cnblogs.com/laozhang-is-phi/p/9511869.html>》, Let's go right JWT
Explanation of , The verification of the interface is realized , You can go and find out , At that time, there was no front end , So we use it directly Swagger
Interface document to manually set the permission validation , Many of my friends didn't understand this group at that time , I also said briefly , Manually in the swagger Input in Header , Every time vue Of
axios Requested Header Add Token, this Token
It's the one we manually configured , Because there was no front and back , So I just talked about this process in a more general way , What about today , For the most part, the next authorization login authentication , Also pave the way for the management background below , Here's the match
Vue front end , Let's talk about how to realize the verification at the same time :



 

The picture above is also very detailed , It is mainly divided into two verifications :


1, Front end verification ( Blue part ), A user visits a page , First, determine whether authentication login is required , Such as managing the backstage , Or order system order page ( The home page and details page naturally do not require users to log in , Shopping cart and order must be logged in , Of course, some tourists can also buy the exception ), And then verify that it exists
Token, Add to existing axios Of Header Middle to request back end API, Otherwise, go to the login page ;

2, Back end validation ( Green part ), This is what we were talking about .net core api That's what I said JWT Authorization verification , According to the current front end axios From the request
Token , Analyze whether it has been tampered with , And whether there will be corresponding permissions , This allows you to return further data ;

At this time, we must have doubts , Now that each interface has defined permissions , Why both sides need verification , Only the back end is needed api One verification is enough , Why bother ? I think so :

First of all, the main purpose of front-end verification is : By manual configuration , Users can take the initiative to obtain Token
, You don't have to get it every time , It also reduces the number of back-end requests , You can't send a request first , Then judge whether the current page needs to log in , Um. , In conclusion ,

The front end is for page level login , The back end is for interface level validation , And also want to put vue The thought of front end Engineering .

 

Two , combination API Design landing page —— Implement back-end validation

1, introduce ElementUI Style frame

  Because after that, we need a management background , So consider adding a framework , What is more popular at present is ElementUI and IView, Today, let's talk about quoting ElementUI

first , In the project implement npm install, After initialization , stay node_modules To see if it exists element-ui folder , without , Then execute
npm i element-ui -S
You can then see that the project has been successfully installed elementui 了



 

then , In the entry profile of the project main.js in , quote
import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css
' Vue.use(ElementUI)
If the item is not reported wrong , At this point, the installation is successful . 

 

2, Add unified login page

first , stay src Of views In folder , add to Login.vue page , And add content :
<template> <el-row type="flex" justify="center"> <el-form ref="loginForm"
:model="user" :rules="rules" status-icon label-width="50px"> <el-form-item
label=" account number " prop="name"> <el-input v-model="user.name"></el-input>
</el-form-item> <el-form-item label=" password " prop="pass"> <el-input v-model="
user.pass" type="password"></el-input> </el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-upload" @click="login"> Sign in </el-button>
</el-form-item> </el-form> </el-row> </template> <script> export default {
methods: { login() {// use elementui validate verification this
.$refs.loginForm.validate(valid => { if (valid) {// This will be rewritten as login information below thank @ Different styles
<https://www.cnblogs.com/zhoudidi/> Note error if (this.user.name === "admin" &&
this.user.pass === "123") { this.$notify({ type: "success", message: " Welcome ," +
this.user.name + "!", duration: 3000 }); this.$router.replace("/"); } else {
this.$message({ type: "error", message: " Wrong user name or password ", showClose: true }); } } else
{return false; } }); } }, data() { return { user: {},// Match the prop Defining data rules:
{// Match the prop Defining rules name: [{ required: true, message: " The user name cannot be empty ", trigger: "blur"
}], pass: [{ required:true, message: " Password cannot be empty ", trigger: "blur" }] } }; } };
</script>
After adding a route , Test whether the page is feasible



 

3, Cooperate with background login request

perfect   BlogController.cs page , Slightly adjusted the lower interface , It's no different from before , And add authority verification



 
/// <summary> /// Get blog list /// </summary> /// <param name="id"></param> ///
<param name="page"></param> /// <param name="bcategory"></param> ///
<returns></returns> [HttpGet] public async Task<object> Get(int id, int page =
1, string bcategory = " Technical blog ") { int intTotalCount = 6; int TotalCount = 1; List
<BlogArticle> blogArticleList =new List<BlogArticle>(); if
(redisCacheManager.Get<object>("Redis.Blog") != null) { blogArticleList =
redisCacheManager.Get<List<BlogArticle>>("Redis.Blog"); } else { blogArticleList
=await blogArticleServices.Query(a => a.bcategory == bcategory);
redisCacheManager.Set("Redis.Blog", blogArticleList, TimeSpan.FromHours(2)); }
TotalCount= blogArticleList.Count() / intTotalCount; blogArticleList =
blogArticleList.OrderByDescending(d => d.bID).Skip((page -1) *
intTotalCount).Take(intTotalCount).ToList();foreach (var item in
blogArticleList) {if (!string.IsNullOrEmpty(item.bcontent)) { int totalLength =
500; if (item.bcontent.Length > totalLength) { item.bcontent =
item.bcontent.Substring(0, totalLength); } } } var data = new { success = true,
page = page, pageCount = TotalCount, data = blogArticleList }; return data; } //
GET: api/Blog/5 /// <summary> /// Get details /// </summary> /// <param
name="id"></param> /// <returns></returns> [HttpGet("{id}", Name = "Get")]
public async Task<object> Get(int id) { var model = await
blogArticleServices.getBlogDetails(id);var data = new { success = true, data =
model };return data; }
 

adjustment LoginController.cs Access to Token method :
/// <summary> /// obtain JWT Methods /// </summary> /// <param name="id">id</param> ///
<param name="sub"> role </param> /// <returns></returns> [HttpGet] [Route("Token")]
public JsonResult GetJWTStr(string name, string pass) { string jwtStr = string
.Empty;bool suc = false; // This is where the user logs in , Access data through database , Operations for assigning permissions // It's dead here if (name == "
admins" && pass == "admins") { TokenModelJWT tokenModel = new TokenModelJWT();
tokenModel.Uid= 1; tokenModel.Role = "Admin"; jwtStr =
JwtHelper.IssueJWT(tokenModel); suc= true; } else { jwtStr = "login fail!!!"; }
var result = new { data = new { success = suc, token = jwtStr } }; return
Json(result); }
 

4, modify Front end Login.vue Login method of the page , Get to Token , And save it to Vuex in

 
<template> <el-row type="flex" justify="center"> <el-card v-if="isLogin">
welcome :admins<br> <br> <el-button type="primary" icon="el-icon-upload" @click="
loginOut"> Log out </el-button> </el-card> <el-form v-else ref="loginForm" :model="
user" :rules="rules" status-icon label-width="50px"> <el-form-item label=" account number "
prop="name"> <el-input v-model="user.name"></el-input> </el-form-item>
<el-form-item label=" password " prop="pass"> <el-input v-model="user.pass" type="
password"></el-input> </el-form-item> <el-form-item> <el-button type="primary"
icon="el-icon-upload" @click="login"> Sign in </el-button> </el-form-item> </el-form>
</el-row> </template> <script> export default { methods: { login: function() {
let that= this; that.$store.commit("saveToken", "");// Clear away token this
.$refs.loginForm.validate(valid => { if (valid) { this.$api.get( "Login/Token",
{ name: that.user.name, pass: that.user.pass }, r=> { if (r.data.success) { var
token = r.data.token; that.$store.commit("saveToken", token);// preservation token this
.$notify({ type:"success", message: " Welcome ," + this.user.name + "!", duration:
3000 }); console.log(that.$store.state.token); this.$router.replace("/"); } else
{this.$message({ type: "error", message: " Wrong user name or password ", showClose: true }); } }
); }else { return false; } }); }, loginOut(){ this.isLogin=false; this
.$store.commit("saveToken", "");// Clear away token } }, data() { return { isLogin:false
, user: {}, rules: { name: [{ required:true, message: " The user name cannot be empty ", trigger: "blur"
}], pass: [{ required:true, message: " Password cannot be empty ", trigger: "blur" }] } }; },
created() {if (window.localStorage.Token&&window.localStorage.Token.length>=128
){this.isLogin=true; } } }; </script>
 

5, modify vuex Warehouse , hold token Deposit in store in
import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); const store =
new Vuex.Store({ // Initialized data state: { formDatas: null, token: "1" }, //
change state It's worth the effort mutations: { getFormData(state, data) { state.formDatas = data;
}, saveToken(state, data) { state.token= data; window.localStorage.setItem("
Token", data);// This is it , Saved to localStorage in } } }); // output module export default store;
 

6, At this time, we need to modify the previous package http.js method , Because at that time, we filtered out the failed methods , We need to open it here , You can modify it by yourself



This is the time , If we log in again , It has changed

 

You can see at this time , We successfully logged in ( Welcome to the top right corner ), then token Also successfully saved to stroe/localStorage in ( Lower console output ),

Because we have added permissions to the blog page , Although we use it admin account number , however Header Has not been added in Token, So it's still here 401, How can we effectively increase requests
Header What about , Please look down , Front end part of authority verification .

 

 

Three , Realize one : Login blocking verification —— Route interception

 1, modify router.js route , Login on demand

Where you need to log in , Add login requirement field ,

Then add beforeEach Hook function ( There is a problem here , Only local cache data can be obtained , Cannot get Vuex , Under study )
import Vue from "vue"; import Router from "vue-router"; import Home from "
./views/Home.vue"; import FormVuex from "./views/FormVuex.vue"; import Content
from "./views/content"; import Login from "./views/Login"; import store from "
./store"; Vue.use(Router); const router = new Router({ mode: "history", base:
process.env.BASE_URL, routes: [ { path:"/", name: "home", component: Home,
meta: { requireAuth:true // Add the field , Indicates that login is required to enter this route } }, { path: "/Vuex", name: "
Vuex", component: FormVuex }, { path: "/Content/:id", name: "Content",
component: Content }, { path:"/Login", name: "Login", component: Login }, {
path:"/about", name: "about", // route level code-splitting // this generates a
separate chunk (about.[hash].js) for this route// which is lazy-loaded when the
route is visited. component: () => import(/* webpackChunkName: "about" */ "
./views/Form.vue") } ] }); router.beforeEach((to, from, next) => { if
(to.meta.requireAuth) {// Determine whether the route requires login permission if
(window.localStorage.Token&&window.localStorage.Token.length>=128) {// adopt vuex
state Gets the current token Does it exist next(); } else { next({ path: '/login', query: {redirect:
to.fullPath}// Route to jump to path As a parameter , Jump to the route after successful login }) } } else { next(); } }) export
default router;
 2, modify http.js Packaging method , Automatically put the Token Add to Header in

Routing settings above , Just right Token Judge , Not added to Header in , There was no verification

be careful : It is currently used localStorage Methods of local storage ( This is inspired by the wechat applet ),

But directly in the router.js Direct access in store Of token attribute , Not available , If you know, please leave a message  

to update : After being reminded by the group's friends There's also a comment box downstairs @ Lu Yao is at ease <https://www.cnblogs.com/xu-jin/>  Reminders of , It's not that you can't get it here , It has to be used
localstoreage To assign a value , because vuex It's just a function of distribution management state , There is no local save function ,

  

 
import store from "../store"; import router from "../router.js"; // to configure API Interface address
var root = "http://localhost:58427/api"; var root1 = "
http://123.206.33.109:8018/api"; // quote axios var axios = require("axios"); //
User defined judgment element type JS function toType(obj) { return {}.toString .call(obj) .match(
/\s([a-zA-Z]+)/)[1] .toLowerCase(); } // Parameter filter function function filterNull(o) { for (
var key in o) { if (o[key] === null) { delete o[key]; } if (toType(o[key]) === "
string") { o[key] = o[key].trim(); } else if (toType(o[key]) === "object") {
o[key]= filterNull(o[key]); } else if (toType(o[key]) === "array") { o[key] =
filterNull(o[key]); } }return o; } // http request Interceptor
axios.interceptors.request.use( config=> { if
(window.localStorage.Token&&window.localStorage.Token.length>=128) {
//store.state.token Cannot get value ??// Judge whether it exists or not token, If it exists , Then each http header All of them token
config.headers.Authorization = window.localStorage.Token; } return config; },
err=> { return Promise.reject(err); } ); // http response Interceptor
axios.interceptors.response.use( response=> { return response; }, error => { if
(error.response) {switch (error.response.status) { case 401: // return 401
eliminate token Information and jump to the login page router.replace({ path: "login", query: { redirect:
router.currentRoute.fullPath } }); } }return
Promise.reject(error.response.data);// Returns the error information returned by the interface } ); /* Interface processing function
This function is different for each item , What I'm adjusting now is that it applies to https://cnodejs.org/api/v1 Interface of , If it's another interface
It needs to be adjusted according to the parameters of the interface . Reference document address :https://cnodejs.org/topic/5378720ed6e2d16149fa16bd
Mainly , The success identification and failure prompt of different interfaces are inconsistent . in addition , The treatment of different projects is also inconsistent , The mistake here is simple alert*/ function
apiAxios(method, url,params, success, failure) { if (params) { params =
filterNull(params); } axios({ method: method, url: url, data: method === "POST"
|| method ==="PUT" ? params : null, params: method === "GET" || method === "
DELETE" ? params : null, baseURL: root, withCredentials: false })
.then(function(res) { success(res.data); }) .catch(function(err) { let res =
err.response;if (err) { window.alert("api error, HTTP CODE: " + res.status); }
}); }// Back in vue Calling interface in template export default { get: function(url, params, success,
failure) {return apiAxios("GET", url, params, success, failure); }, post:
function(url,params, success, failure) { return apiAxios("POST", url, params,
success, failure); }, put: function(url,params, success, failure) { return
apiAxios("PUT", url, params, success, failure); }, delete: function(url, params
, success, failure) {return apiAxios("DELETE", url, params, success, failure);
} };
Run project view :



 

You can see from the observation , Our first click Home When , It's found that it's jumping to Login page , And then log in , Auto jump home page , And get the data successfully , Login successful !

Then log out , Found that the home page has been unable to enter , Exit succeeded !

 

Four , explain

  Today, because of the time , No Vuex How to obtain in the route , Instead of using a local cache , If you have any friends you know , Please leave a message ~~~ esteem it a favor ,

Five ,CODE

front end :
https://github.com/anjoy8/Blog.Vue <https://github.com/anjoy8/Blog.Vue>

back-end :

https://github.com/anjoy8/Blog.Core <https://github.com/anjoy8/Blog.Core>