You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// CORS middlewareconstallowCrossDomain=function(req,res,next){res.header('Access-Control-Allow-Origin','*')res.header('Access-Control-Allow-Methods','*')res.header('Access-Control-Allow-Headers','*')next()}app.use(allowCrossDomain)
很多开发者都会使用 CORS 库,但我们并没有任何复杂的配置,所以适合就好。
接下来,定义注册新用户的路由:
router.post('/register',(req,res)=>{db.insert([req.body.name,req.body.email,bcrypt.hashSync(req.body.password,8)],err=>{if(err){returnres.status(500).send('There was a problem registering the user.')}db.selectByEmail(req.body.email,(err,user)=>{if(err){returnres.status(500).send('There was a problem getting user')}lettoken=jwt.sign({id: user.id},config.secret,{expiresIn: 86400})res.status(200).send({auth: true,
token,
user,})})})})
router.post('/register-admin',(req,res)=>{db.insertAdmin([req.body.name,req.body.email,bcrypt.hashSync(req.body.password,8),1,],err=>{if(err){returnres.status(500).send('There was a problem registering the user.')}db.selectByEmail(req.body.email,(err,user)=>{if(err){returnres.status(500).send('There was a problem getting user.')}lettoken=jwt.sign({id: user.id},config.secret,{expiresIn: 86400})res.status(200).send({auth: true,
token,
user,})})})})router.post('/login',(req,res)=>{db.selectByEmail(req.body.email,(err,user)=>{if(err){returnres.status(500).send('Error on the server.')}if(!user){returnres.status(404).send('No user Found.')}letpasswordIsValid=bcrypt.compareSync(req.body.password,user.user_pass)if(!passwordIsValid){returnres.status(401).send({auth: false,token: null})}lettoken=jwt.sign({id: user.id},config.secret,{expiresIn: 86400})res.status(200).send({auth: true,
token,
user,})})})
constsqlite3=require('sqlite3').verbose()classDB{constructor(file){this.db=newsqlite3.Database(file)this.createTable()}createTable(){constsql=` CREATE TABLE IF NOT EXISTS user ( id integer PRIMARY KEY, name text, email text UNIQUE, user_pass text, is_admin integer)`returnthis.db.run(sql);}selectByEmail(email,callback){returnthis.db.get(`SELECT * FROM user WHERE email = ?`,[email],function(err,row){callback(err,row)})}insertAdmin(user,callback){returnthis.db.run('INSERT INTO user (name,email,user_pass,is_admin) VALUES (?,?,?,?)',user,(err)=>{callback(err)})}selectAll(callback){returnthis.db.all(`SELECT * FROM user`,function(err,rows){callback(err,rows)})}insert(user,callback){returnthis.db.run('INSERT INTO user (name,email,user_pass) VALUES (?,?,?)',user,(err)=>{callback(err)})}}module.exports=DB
<template><divclass="hello"><h1>This is homepage</h1><h2>{{msg}}</h2></div></template><script>exportdefault{data(){return{msg: 'Hello World!'}}}</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<stylescoped>
h1, h2 {font-weight: normal;}
ul {list-style-type: none;padding: 0;}
li {display: inline-block;margin: 010px;}
a {color: #42b983;}</style>
将 jwt token 和 user 信息存储到 localStorage,以便在应用随时获取。当然,我们还会将认证处理后的用户重定向至认证前的路由。若用户来自登录路由,则取决于用户类型。
接下来,创建 Register.vue 文件并添加以下内容:
<template><div><h4>Register</h4><form><labelfor="name">Name</label><div><inputid="name"type="text"v-model="name"requiredautofocus></div><labelfor="email">E-Mail Address</label><div><inputid="email"type="email"v-model="email"required></div><labelfor="password">Password</label><div><inputid="password"type="password"v-model="password"required></div><labelfor="password-confirm">Confirm Password</label><div><inputid="password-confirm"type="password"v-model="password_confirmation"required></div><labelfor="password-confirm">Is this an administrator account?</label><div><selectv-model="is_admin"><optionvalue=1>Yes</option><optionvalue=0>No</option></select></div><div><buttontype="submit" @click="handleSubmit">
Register
</button></div></form></div></template>
<template><divclass="hello"><h1>Welcome to administrator page</h1><h2>{{msg}}</h2></div></template><script>exportdefault{data(){return{msg: 'The superheros'}}}</script><stylescoped>
h1, h2 {font-weight: normal;}
ul {list-style-type: none;padding: 0;}
li {display: inline-block;margin: 010px;}
a {color: #42b983;}</style>
以上是当用户访问管理员页面时挂载的组件。
最后,创建 UserBoard.vue 文件并添加以下内容:
<template><divclass="hello"><h1>Welcome to regular users page</h1><h2>{{msg}}</h2></div></template><script>exportdefault{data(){return{msg: 'The commoners'}}}</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<stylescoped>
h1, h2 {font-weight: normal;}
ul {list-style-type: none;padding: 0;}
li {display: inline-block;margin: 010px;}
a {color: #42b983;}</style>
原文:Vue Authentication And Route Handling Using Vue-router
Vue 是一个渐进式 JavaScript 框架,它使得前端应用的构建变得简单。搭配 vue-router 就能构建拥有复杂动态路由的高性能应用。vue-router 是一个高效的工具,它能在 Vue 应用中无缝地处理用户认证。在本教程中,我们将看到如何使用 vue-router 处理用户认证和应用各部分的访问控制。
开始
通过 Vue cli 创建一个 Vue 应用:
根据安装提示完成应用的安装。如果某个选项不确定,可敲 return 键(既 enter 键)输入默认值以进行下一步。当询问是否安装 vue-router 时,就确认安装。
目录
启动 Node.js 服务
下一步是启动 Node.js 服务以处理用户认证功能。我们将使用 SQLite 作为数据库。通过以下命令安装 SQLite 驱动:
因为需要与密码打交道,所以需要对密码进行哈希加密。我们将使用 bcrypt 完成哈希加密操作。通过以下命令安装:
当用户向应用需要认证的部分发送请求时,我们如何进行用户认证呢?对此,我们将使用 JWT 解决这个问题。通过以下命令安装 JWT 模块:
为了能读取
json
请求数据,我们需要body-parser
模块。通过以下命令安装:现在万事俱备,让我们创建一个简单的 Node.js 服务以处理用户认证。创建名为 server 的新目录,它将存放所有 Node.js 后端文件。在该目录下,创建名为
app.js
文件,其内容如下:引入应用所需的所有模块、定义数据库、创建一个 express 服务和一个 express 路由。
现在,让我们定义 CORS 中间件,以确保不陷入任何跨域问题:
很多开发者都会使用 CORS 库,但我们并没有任何复杂的配置,所以适合就好。
接下来,定义注册新用户的路由:
上述代码做了以下事情:向数据库方法(后续定义)传递了请求体(request body)和一个用于处理数据库响应的回调函数。同时,也定义了错误检查,以确保能向用户提供精确的反馈信息。
当用户成功注册时,我们通过 email 选择用户,并通过
jwt
模块为其创建用户认证 token。而 config 文件内的 secret key 则用于对用户认证进行签名。这样,我们就能验证发送到服务器的 token,避免伪造身份。现在,定义用于注册管理员和登录的路由,两者与上述的注册逻辑类似:
对于登录,我们使用 bcrypt 模块对哈希后的密码和用户提供的密码进行比较。若两者相同,则登录成功。反之,则登录失败,并向用户进行反馈。
通过 express 服务器让应用可响应请求:
我们在
port: 3000
创建了一个服务,任意动态生成的端口亦可(heroku 提供 生成动态端口服务)。然后,在同样目录下创建
config.js
文件:最后,创建
db.js
文件:为数据库创建一个类以抽象出所需的基本函数。你可能希望在此使用更通用和可复用的方法来进行数据库操作,甚至是使用 promise 来提高其效率。既需要一个所有类可共用的库(特别是使用 MVC 架构的应用)。
服务器端已完成开发,接下来让我们看看 Vue 应用。
更新 Vue-router 文件
该 vue-router 文件在
./src/router
目录下。我们将在index.js
文件定义应用的所有路由。这与服务器不同,切记混淆。打开该文件并添加以下内容:
引入所有组件,这些组件将在后续创建。
定义应用的路由:
Vue router 可定义元数据(meta),可基于此指定额外行为。上述代码,我们分别定义了 访客(未认证用户可见)、认证用户(认证用户可见)和管理员的路由。
基于元数据(meta)处理路由请求:
Vue-router 拥有一个 beforeEach 方法,其在每个路由处理前调用。可利用此特性定义检查条件并限制用户访问权限。该方法共接收 3 个参数——to、from 和 next。其中,
to
是用户将去哪、from
是用户来自哪、next
是一个继续用户请求处理的回调函数。因此,检查操作将在to
对象上进行。我们将进行以下几点检查:
requireAuth
,则检查jwt
token,以表明用户是否已登录。requireAuth
且要求是管理员,则检查已登录用户是否是管理员。guest
,则检查用户是否已登录。我们根据检查内容对用户请求进行重定向。由于上述代码使用路由的 name 属性进行重定向,需确保应用拥有该 name 属性的路由。
定义组件
下面将定义一些组件,用于测试上面构建的内容。在
./src/components/
目录下,打开HelloWorld.vue
文件并输入以下内容:在同样目录下,创建
Login.vue
文件并输入以下内容:上面是 HTML 模板,下面将为其定义处理登录的脚本:
此时,我们将
email
和password
数据绑定到表单域以收集用户输入的信息。最终,将用户提供的信息发送到服务器以验证凭证。处理服务器返回的信息:
将
jwt
token 和user
信息存储到 localStorage,以便在应用随时获取。当然,我们还会将认证处理后的用户重定向至认证前的路由。若用户来自登录路由,则取决于用户类型。接下来,创建
Register.vue
文件并添加以下内容:定义处理注册的脚本:
这与
Login.vue
文件结构类似。创建
Admin.vue
并添加以下内容:以上是当用户访问管理员页面时挂载的组件。
最后,创建
UserBoard.vue
文件并添加以下内容:以上是当用户访问 dashboard 页面看到组件。
以上就是所需的所有组件。
全局安装 Axios
对于服务端请求,我们将使用 axios。axios 是一个基于 promise 的 HTTP 库,适用于浏览器和 Node.js。使用以下命令安装 axios:
为了让所有组件获取它,打开
./src/main.js
文件并添加以下内容:通过定义
Vue.prototype.$http = Axios
改变 Vue 以添加 axios。这样我们就能在所有组件通过this.$http
使用 axios。运行应用
至此已完成整个应用的开发。由于 Node.js 服务器与 Vue 应用相互依存,需要同时运行。
通过添加脚本,方便启动 Node.js 服务器。打开
package.json
文件并添加以下内容:server
脚本是为了便于启动 Node.js 服务器。现在执行以下命令以启动服务器:可看到以下类似内容:
创建另一个终端实例并运行 Vue 应用:
这将会构建所有资源并启动应用。
总结
在本教程中,我们学到了如何使用 vue-router 为路由定义检查条件,防止用户访问特定路由,也学到了如何根据认证状态进行重定向。当然,用户认证是通过我们建立的小型 Node.js 服务器进行处理。
其实,我们所做的访问控制与 Laravel 之类的框架类似。你可以看看 vue-router 还有什么有趣的事情可做。
The text was updated successfully, but these errors were encountered: