问题描述
希望一切都很好。我正在尝试创建一个对用户进行身份验证的登录系统,然后将其重定向到其仪表板。我正在使用Expressjs和HBS创建此文件,并将数据存储在MongoDB数据库中。
到目前为止我已经完成的事情:
当用户提交表单时,我使用POST从‘/admin/login’
提取请求,该请求从客户端获取用户输入(电子邮件和密码)。在服务器端,该数据用于在数据库中查找用户并生成令牌。然后,该令牌在响应中发送回客户端,然后在获取请求的标头中使用回送给服务器的‘/admin/me’
,使用GET使用令牌来验证用户是否已登录。一切似乎都按计划进行。
我被困的地方:
用户通过身份验证后,我想使用HBS渲染仪表板(不同的html页面)。我可以使用‘/admin/me’
从res.send()
发送回客户端响应,但是我想使用res.render()
来渲染hbs模板。即使我不使用.then()
来处理‘/admin/me’
返回的诺言,也无法得到res.render()
来渲染要渲染的.hbs文件。我在做什么错了?
这是我第一次尝试这样做,我以为自己对自己的所作所为有所了解,但是我觉得自己的逻辑上有漏洞,而且我缺少一些东西。也许我只是不明白-__-。不过没有错误代码,这很酷。
谢谢您的时间,这对我来说意义重大。我期待着您的答复。有一个好吧。
我的文件结构:
/config
=dev.env
/dist
=/css
==style.css
=/js
==bundle.js
=/views
==/pages
===admin.hbs
===index.hbs
/node_modules
/src
=/db
==mongoose.js
=/middleware
==admin_auth.js
=/models
==admin.js
=/routers
==admin.js
=app.js
=dom_elem.js
=hbs_config.js
=index.js
=server.js
=/scss
=/views
==/pages
===admin.js
===index.hbs
package.json
webpack.config.js
html格式:
/dist/views/pages/index.hbs
<form class="form--login" id="form-login-admin"
<div class="login-form-group"
<label for="email-admin"><h4>e-mail:</h4></label
<input type="email" name="email-admin" id="email-admin"
</div
<div class="login-form-group"
<label for="password-admin"><h4>password:</h4></label
<input type="password" name="password-admin" id="password-admin"
</div
<button class="btn-login" id="btn-login-admin" type="submit">Login</button
</form>
hbs配置:
/src/js/hbs_config.js
const path = require( 'path' ); // include path module
// define path for views
const views_path = path.join( __dirname,'../../dist/views/pages' );
// define path for partials
const partials_path = path.join( __dirname,'../../dist/views/partials' );
module.exports = {
views_path,partials_path
}
其中设置了快速应用程序的地方:
/src/js/app.js
const path = require( 'path' ); // include path module
const express = require( 'express' ); // include express js module
const bodyParser = require( 'body-parser' ); // include json body parser
require( './db/mongoose' ); // import mongoose db
const { views_path,partials_path } =require( './hbs_config' )
const hbs = require( 'hbs' ); // import hbs module
const adminRouter = require( './routers/admin' );
// define public path for server
const public_path = path.join( __dirname,'../../dist' );
// create application/json parser
const jsonParser = bodyParser.json();
// create express application
const app = express();
// set the view engine
app.set( 'view engine','hbs' );
// set directory for views
app.set( 'views',views_path );
// set directory for partials
hbs.registerPartials( partials_path );
// parse data objects from request payloads into json objects
app.use( express.json() );
app.use(bodyParser.json());
// use public path
app.use( express.static( public_path ) );
app.use( adminRouter );
// export application
module.exports = app;
服务器启动的位置:
/src/js/server.js
const app = require( './app' ); // imnport application
app.get( '/',( req,res ) => {
res.render('index.hbs'); // <-this works just fine
} );
// set PORT
const port = process.env.PORT;
// start server
app.listen( port,() => {
console.log( `server is running on port: ${port}` );
} );
验证用户身份的功能:
/scr/js/middleware/admin_auth.js
const jwt = require( 'jsonwebtoken' ); // import json web token module
const Admin = require( '../models/admin' ); // import Model for 'admin'
// function to authenticate the admin
const admin_auth = async ( req,res,next ) => {
try {
// grab token from http request header
const token = req.header( 'Authorization' ).replace( 'Bearer ','' );
// decode the hashed token
const decoded = jwt.verify( token,process.env.JWT_SECRET );
// get admin by id and token
const admin = await Admin.findOne( { _id: decoded._id,'tokens.token': token } );
// if admin is undefined...
if ( !admin ) {
// ...throw error
throw new Error();
}
// store token in request
req.token = token;
// store admin in request
req.admin = admin;
// end async/await
next();
} catch ( err ) { // catch errors
console.log(err);
// response with error status and error message
res.status( 401 ).send( { error: 'Authentication required.' } );
}
};
// export admin authentication functions
module.exports = admin_auth;
路线:
/src/js/routers/admin.js
const express = require( 'express' ); // import express js module
const bodyParser = require( 'body-parser' );
const router = new express.Router(); // instantiate express js router
const Admin = require( '../models/admin' ); // import model for admin
const adminAuth = require( '../middleware/admin_auth' ); // import authentication function for admin
// post request to login admin
router.post( '/admin/login',async ( req,res ) => {
try {
const admin = await Admin.findByCredentials( req.body.email,req.body.password );
const token = await admin.generateAuthToken();
res.status(200).send({"token": token});
} catch ( e ) {
res.status( 400 ).send( {"message": e.message} );
}
} );
// get request to render admin page
router.get( '/admin/me',adminAuth,res ) => {
// res.render( 'admin.hbs' ); <-doesn’t render the template :(
// return res.render( ‘admin.hbs’ ) // I tried returning res.render()
res.send({"message": "hello from /admin/me"} ); // <-sends the response back
} );
客户端的javascript:
/src/js/index.js
const elements = require( './dom_elem' );
// if the form is in the DOM
if( elements.admin_login_form ) {
// when the user clicks ‘login’
elements.admin_login_form.addEventListener( 'submit',( e ) => {
e.preventDefault();
console.log( 'user clicked submit' );
// input from DOM
const email = elements.admin_login_email;
const password = elements.admin_login_password;
// fetch request using POST sending the email and password
fetch('/admin/login',{
method: 'POST',headers: {
'Content-Type': 'application/json','Accept': 'applicaiton/json'
},body: JSON.stringify({email: email.value,password: password.value})
})
.then(response => {
return response.json();
})
.then( data => { // responds back with a token
console.log('token from \'/admin/login\’: ',data);
// fetch /admin/me GET request with token in header
fetch( '/admin/me',{
headers: {
'Authorization' : `Bearer ${data.token}`,‘Accept’: ’text/html’ // i’ve tried leaving the ‘Accept’ header blank and with ‘application/json’
}
} )
.then( response => { // even when I don’t handle the promise res.render() doesn’t work
return response.json(); // I’ve tried ‘return response;’ and not handling the data
} )
.then( data => {
console.log( 'result: ',data.message ); // <- I get the response from the ‘/admin/me’ endpoint
} )
.catch( e => {
console.log( 'error from \'/admin/me\': ',e.message )
} )
} )
.catch( e => {
console.log('error from \'/admin/login\': ',e.message
);
} )
closeAdminLogin();
email.value = '';
password.value = '';
} );
结果的屏幕截图: screenshot_of_results
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)