当前位置: 首页 > news >正文

美国 做网站上海品牌推广公司

美国 做网站,上海品牌推广公司,购买商标,WordPress 聊天小工具1. 环境准备2. 创建项目3. Vue配置步骤一: 安装包步骤二: 配置文件步骤三: 页面文件 4. 后台配置 在本教程中,我将利用Visual Studio 2022的强大集成开发环境,结合Vue.js前端框架和ASP.NET Core后端框架,从头开始创建一个具备用户登录与权限验…

  • 1. 环境准备
  • 2. 创建项目
  • 3. Vue配置
    • 步骤一: 安装包
    • 步骤二: 配置文件
    • 步骤三: 页面文件
  • 4. 后台配置

在本教程中,我将利用Visual Studio 2022的强大集成开发环境,结合Vue.js前端框架和ASP.NET Core后端框架,从头开始创建一个具备用户登录与权限验证功能的Web应用程序。我们将充分利用Visual Studio的内置工具和模板来简化开发流程。

1. 环境准备

Visual Studio 2022,Vue3

2. 创建项目

打开Visual Studio 2022,选择“创建新项目”。在项目模板搜索框中输入“Vue and ASP.NET Core”,选择模板后点击“下一步”。
按照图中配置:
在这里插入图片描述
生成目录如下:
在这里插入图片描述

3. Vue配置

步骤一: 安装包

右键npm->安装新的npm包

  • element-plus UI包
  • @element-plus/icons-vue UI图标包
  • axios 发送请求的包
  • qs 发送请求时序列化的包
  • vue-router vue路由
  • jwt-decode 令牌解码

步骤二: 配置文件

  • 封装axios
    新建axios.js文件,内容如下:

    // axios.jsimport axios from 'axios';
    import PLATFROM_CONFIG from '../public/config';const instance = axios.create({baseURL: PLATFROM_CONFIG.baseURL, // 替换为实际的 API 地址timeout: 10000,
    });instance.defaults.headers.post['Content-Type'] = 'application/json';// 添加请求拦截器
    axios.interceptors.request.use((config) => {// 在发送请求之前做些什么return config;
    }, function (error) {// 对请求错误做些什么return Promise.reject(error);
    });// 添加响应拦截器
    axios.interceptors.response.use(function (response) {// 对响应数据做点什么if (response.status === 200) {return Promise.resolve(response);} else {return Promise.reject(response);}
    }, function (error) {// 对响应错误做点什么return Promise.reject(error);
    });export const get = (url, params) => {return instance.get(url, { params });
    };export const post = (url, data) => {// data = QS.stringify(data);return instance.post(url, data);
    };
  • 创建路由
    新建router文件夹,并新建router.js文件

import { createRouter, createWebHashHistory } from 'vue-router'import qs from 'qs';
import { ElMessage } from 'element-plus'import { post } from '../axios';import Home from '../components/Home.vue'
import Setting from '../components/Setting.vue'
import Login from '../components/Login.vue'
import LoginOut from '../components/LoginOut.vue'// 路由配置
const routes = [{ path: '/', component: Home },{ path: '/Login', component: Login },{ path: '/Setting', component: Setting, meta: { requiresAuth: true, role: 'ShortcutManage;' } },{ path: '/LoginOut', component: LoginOut },
]const router = createRouter({history: createWebHashHistory(),routes,
})
// 路由守卫,在这里创建验证的流程
router.beforeEach((to, from, next) => {const accessToken = localStorage.getItem('accessToken');if (to.meta.requiresAuth && !accessToken) {// 如果需要认证并且没有令牌,则重定向到登录页next('/Login');} else {if (to.meta.requiresAuth) {// 如果有令牌判断令牌是否过期//判断令牌是否过期const decodedToken = jwtDecode(accessToken);const expirationTime = decodedToken.exp * 1000;const isTokenExpired = expirationTime < Date.now();// 已经过期if (isTokenExpired) {next('/LoginOut');} else { // 没有过期// 判断是否需要指定权限if (typeof (to.meta.role) !== 'undefined' && to.meta.role != null) {let USER_INFO = qs.parse(localStorage.getItem("userInfo"))post("Login/ValidPerm", { username: USER_INFO.ad, userPowr: to.meta.role }).then(res => {next();}).catch(err => {console.log(err)ElMessage({message: '您没有权限,请联系管理员!',type: 'warning',})})} else {next();}}} else {next();}}
});export default router
  • 配置main.js
import './assets/main.css'import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import { ElMessage} from 'element-plus'
import 'element-plus/dist/index.css'
import router from './router/router'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import { get, post } from './axios';
import App from './App.vue'
import * as utils from './utils';
import qs from 'qs'import ELHeader from './components/custom/ElHeader.vue'
import ElAside from './components/custom/ElAside.vue'const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)
}Object.entries(utils).forEach(([key, value]) => {app.config.globalProperties[`$${key}`] = value;
});app.config.globalProperties.$get = get;
app.config.globalProperties.$qs = qs;
app.config.globalProperties.$post = post;
app.config.globalProperties.$message = ElMessage;app.config.globalProperties.$USER_INFO = qs.parse(localStorage.getItem("userInfo"))app.use(ElementPlus)
app.use(router)app.component('ELHeader', ELHeader).component('ELAside',ElAside); app.mount('#app')

步骤三: 页面文件

  • 登陆页面Login.vue
<template><el-form :model="loginForm" ref="loginForm" :inline="false" size="large"><el-form-item prop="Username" :rules="{required: true,message: 'Username can not be null',trigger: 'blur',
}"><el-input v-model="loginForm.Username" placeholder="Okta Account"><template #prepend><el-icon><User /></el-icon></template></el-input></el-form-item><el-form-item prop="Password" :rules="{required: true,message: 'Password can not be null',trigger: 'blur',
}"><el-input type="password" v-model="loginForm.Password" placeholder="Okta Password"><template #prepend><el-icon><Lock /></el-icon></template></el-input></el-form-item><el-form-item><el-button class="login-btn" type="primary" @click="loginOn">登陆</el-button></el-form-item></el-form>
</template>
<script lang="js">
import { defineComponent } from 'vue';
export default defineComponent({data() {return {loginForm: {Username: '',Password: '',auth: "ShortcutLinks"}}},methods: {loginOn() {this.$refs.loginForm.validate((valid) => {if (valid) {let that = thisthis.$post("/Login/LoginVerify", this.loginForm).then(res => {if (res.data.success) {// 检测是否有TokenlocalStorage.setItem('accessToken', res.data.data.token)let userInfo = res.data.datauserInfo.token = nulllocalStorage.setItem('userInfo', this.$qs.stringify(userInfo))that.$router.push('/')} else {this.$message({showClose: true,message: res.data.message,type: 'warning',})}}).catch(err => {console.error(err)})} else {console.log('error submit!')return false}})}},mounted(){this.Yaer = new Date().getFullYear()}
})
</script>
  • 注销界面LoginOut.vue
<template><div>退出登陆成功!</div>
</template><script lang="js">
import { defineComponent } from 'vue';export default defineComponent({data() {return {}}, mounted() {localStorage.removeItem('userInfo');localStorage.removeItem('accessToken');  this.$router.push('/Login');}
})
</script>
  • 修改App.vue

<template><router-view></router-view>
</template><style scoped></style>

4. 后台配置

创建一个生成Token的工具类TokenService

    public class TokenService{private readonly string _secretKey;private readonly string _issuer;private readonly string _audience;public TokenService(string secretKey, string issuer, string audience){_secretKey = secretKey;_issuer = issuer;_audience = audience;}public string GenerateToken(string username){var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_secretKey));var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);var claims = new[]{new Claim(ClaimTypes.Name, username),// Add additional claims as needed};var token = new JwtSecurityToken(_issuer,_audience,claims,expires: DateTime.Now.AddMonths(1), // Token expiration timesigningCredentials: credentials);return new JwtSecurityTokenHandler().WriteToken(token);}}

配置跨域Program.cs`
在Buidl()之前增加:

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";builder.Services.AddCors(options =>
{options.AddPolicy(name: MyAllowSpecificOrigins, policy =>{policy.WithOrigins("*").AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();});
});

登陆验证
LoginController.cs

 [HttpPost("LoginVerify")]public async Task<Result<LoginInfo>> LoginVerify([FromBody] LoginModel loginModel){if (string.IsNullOrEmpty(loginModel.Username) || string.IsNullOrEmpty(loginModel.Password)){return Result<LoginInfo>.Fail("用户名或密码不能为空!");}if (string.IsNullOrEmpty(loginModel.Auth) || !"ShortcutLinks".Equals(loginModel.Auth)){return Result<LoginInfo>.Fail("令牌识别错误!");}string responseContent = await IsValidUser(loginModel.Username, loginModel.Password);if ("Unauthorized".Equals(responseContent)){return Result<LoginInfo>.Fail("验证失败!");}if ("The user name or password is incorrect.".Equals(responseContent)){return Result<LoginInfo>.Fail("用户名或密码错误!");}try{// 加密秘钥,可以自定义string key = "Ns9XoAdW7Pb3Cv9Fm2Zq4t6w8y/B?E(H+MbQeThWmZq4t7w9z$C&F)J@NcRfUjXn2r5u8x/A%D*G-KaPdSgVkYp3s6v9y";// 我自己的登陆验证方法,根据实际情况可以修改LoginInfo loginInfo = JsonConvert.DeserializeObject<LoginInfo>(responseContent);// 生成验证的Tokenvar tokenService = new TokenService(key, "ShortcutLinksServer", "ShortcutLinksClient");// 为Token添加一个标识,我这里使用的用户的ADvar token = tokenService.GenerateToken(loginInfo.AD);loginInfo.token = token;// 生成的信息返回前天return Result<LoginInfo>.Suc(loginInfo);}catch (Exception){return Result<LoginInfo>.Fail("登陆失败!");}}

文章转载自:
http://fuse.c7500.cn
http://antilepton.c7500.cn
http://agaze.c7500.cn
http://irreproachable.c7500.cn
http://portulacaceous.c7500.cn
http://hypophysectomy.c7500.cn
http://opalescent.c7500.cn
http://grackle.c7500.cn
http://cosher.c7500.cn
http://might.c7500.cn
http://teleportation.c7500.cn
http://kingmaker.c7500.cn
http://jesuitry.c7500.cn
http://harlequinade.c7500.cn
http://unpolled.c7500.cn
http://overburden.c7500.cn
http://rhythmocatechism.c7500.cn
http://aerotrack.c7500.cn
http://ichthyosis.c7500.cn
http://linkwork.c7500.cn
http://cyetic.c7500.cn
http://barometric.c7500.cn
http://throat.c7500.cn
http://pisiform.c7500.cn
http://tetracarpellary.c7500.cn
http://bootee.c7500.cn
http://dynistor.c7500.cn
http://atelier.c7500.cn
http://carbonic.c7500.cn
http://obstruct.c7500.cn
http://sexagenary.c7500.cn
http://untwist.c7500.cn
http://tracheary.c7500.cn
http://epistemology.c7500.cn
http://manyatta.c7500.cn
http://britishly.c7500.cn
http://throaty.c7500.cn
http://symplectic.c7500.cn
http://lyre.c7500.cn
http://intertestamental.c7500.cn
http://thermometry.c7500.cn
http://skippingly.c7500.cn
http://tedder.c7500.cn
http://igraine.c7500.cn
http://tribology.c7500.cn
http://diemaker.c7500.cn
http://yodel.c7500.cn
http://orinasal.c7500.cn
http://ovr.c7500.cn
http://cognate.c7500.cn
http://binaural.c7500.cn
http://pulmometer.c7500.cn
http://amphipathic.c7500.cn
http://autoplasty.c7500.cn
http://barytes.c7500.cn
http://dancetty.c7500.cn
http://depaint.c7500.cn
http://moneme.c7500.cn
http://vaginae.c7500.cn
http://solan.c7500.cn
http://epileptoid.c7500.cn
http://reft.c7500.cn
http://roadbook.c7500.cn
http://nile.c7500.cn
http://lipper.c7500.cn
http://pilaster.c7500.cn
http://diaconal.c7500.cn
http://xenium.c7500.cn
http://implicate.c7500.cn
http://rouille.c7500.cn
http://nodal.c7500.cn
http://rapidly.c7500.cn
http://argentous.c7500.cn
http://leidenfrost.c7500.cn
http://knesset.c7500.cn
http://lactoprotein.c7500.cn
http://microcosmic.c7500.cn
http://tammy.c7500.cn
http://enneahedron.c7500.cn
http://cameralism.c7500.cn
http://tungus.c7500.cn
http://ommiad.c7500.cn
http://bicuspidate.c7500.cn
http://kdc.c7500.cn
http://marhawk.c7500.cn
http://cyclopia.c7500.cn
http://halfhearted.c7500.cn
http://palstave.c7500.cn
http://rouleau.c7500.cn
http://cutch.c7500.cn
http://synesthete.c7500.cn
http://frequenter.c7500.cn
http://unaccepted.c7500.cn
http://newscast.c7500.cn
http://huh.c7500.cn
http://mpm.c7500.cn
http://sheepshead.c7500.cn
http://indicator.c7500.cn
http://polyphyodont.c7500.cn
http://arrestant.c7500.cn
http://www.zhongyajixie.com/news/79359.html

相关文章:

  • 北京 做网站比较有名的营销渠道
  • saas建站系统是怎么实现的seo优化在哪里学
  • 风云办公ppt模板网站平台引流推广怎么做
  • 网站设计规划 优帮云国内电商平台有哪些
  • 注册网站域名用什么好处最新国际足球世界排名
  • 企业网站代码免费卖货平台
  • inurl 网站建设国内重大新闻
  • 做的网站文字是乱码站长之家的作用
  • 生物科技公司网站模板下载月入百万的游戏代理
  • 信用门户网站建设山西太原网络推广
  • 可以做哪些网站自己怎么创建网站
  • 怎么做整人点不完的网站网站接广告平台
  • 手机网站 分享按钮网络营销的类型
  • 淘宝网站建设可靠软文广告营销
  • 优质的天津网站建设关键词优化的五个步骤
  • it人力外包服务公司西安seo按天收费
  • 刚做的网站搜全名查不到网上的推广公司
  • 兰州网站建设怎么选曼联官方发文
  • web前端可以自学吗武汉seo优化
  • 红色企业网站模板百度广告投放电话
  • 国外有哪些网站是做弱电的沧州网站建设推广
  • 南通网站推广公司新发布的新闻
  • 心理网站开发背景html友情链接代码
  • 企业融资贷款seo工资多少
  • 深圳燃气公司招聘信息seo网站分析报告
  • 宁波网站建设方式推广引流app
  • wordpress菜单参数设置阿亮seo技术顾问
  • 宿迁房产网官网备案北京seo优化哪家好
  • 清河做网站引流推广方案
  • 怎么用视频做网站背景2020站群seo系统