首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用户认证、管理

用户认证、管理
EN

Code Review用户
提问于 2019-11-18 21:12:04
回答 1查看 164关注 0票数 2

最近,我开始在前端学习JavaScript、nodeJS和reactJS,我还有一些关于在JavaScript世界中应用的最佳实践的问题。我想征求关于如何改进我的代码的意见。

从一个示例开始:我有两个函数,具有不同的处理承诺的方法。

在这里,我有一个添加用户的路由:

代码语言:javascript
复制
 addUsers(req,res,next) {
    try {
        const {name,email,login} = req.body;
        User.existLogin(req.body.login)
        .then(async result => {
            if(!result){
                const password = await bcrypt.hashSync(req.body.password, 10);
                User.create({ 
                    name, email, login, password }).then(result => {
                    res.status(201).json({Results: result.dataValues})
                })
            }else{
                return res.status(409).json({message: 'Login already exists'}); 
            }
        })
    } catch (error) {
        res.status(500).json({error: error})
    }
}

在这里,我还有另一个功能要登录:

代码语言:javascript
复制
async login(req,res){
    const  user  = await User.existLogin(req.body.login);
    if (!user) { return res.status(400).json({result: 'Login is wrong '});} 
    const isPassword = await User.isPassword(user.dataValues.password, req.body.password);
    if (!isPassword) { return res.status(400).json({result: 'Password is wrong '}); } 
    const jwt = auth.signjwt(auth.payload(user));
    console.log(jwt);
    res.status(200);
    res.json(jwt);
}

从这个角度看,在我看来,登录功能似乎更干净,但我怀疑如果真的是您的,我可以在两种方法中的一种改进(我遵循不同的逻辑来做到这两种逻辑)。

我有一个auth文件夹,在这里我导出函数,比如我的有效负载、我的标志、我的中间件来验证我的jwt,但是我不知道这是否是一个正确的决定。

代码语言:javascript
复制
const jwt = require('jsonwebtoken');
const User = require('../models/User')
const config= require('../config/dbconfig');
const moment = require('moment');

module.exports = {
    signjwt (payload) {
        return jwt.sign(payload, 
            config.secretToken
                   )
    },
    payload (usuario) {
        return {
            sub: usuario.id,
            name: usuario.nome,
            email: usuario.email,
            login: usuario.username,
            admin: true,
            iat: Math.floor(moment.now()/1000), // Timestamp de hoje
            exp: moment().add(10, 'minutes').unix() // Validade de 2 dias
        }
    },
    async auth(req,res,next){
        const token = req.header('Authorization');
        console.log(token);
        if(!token) return res.status(401).json('Unauthorized');
        try{
            const decoded = jwt.verify(token,config.secretToken);
            const user = await User.findByPk(decoded.sub);
            console.log(user);
            if(!user){
                return res.status(404).json('User not Found');
            }
            res.json(user);
            next();
        }catch(error){
            console.error(error);
            res.status(400).json('Invalid Token');
        }
    }
}
EN

回答 1

Code Review用户

发布于 2021-04-26 21:33:33

最初的想法:

这段代码看起来非常..。压缩,无需严格要求。我注意到的另一件事是在这里显示的嵌套级别。

一般来说,你决定如何处理承诺并没有什么特别的区别,在绝大多数情况下,这只是个人偏好的问题。

您不需要担心的一件事是专门处理承诺拒绝,因为express会自动将抛出的错误转换为适当的响应。这就是login所利用的看起来如此干净的地方。

我注意到的最后一点是代码中显示的不一致。

Inconsistencies:

比较以下示例中空格的使用情况:

代码语言:javascript
复制
const  user   = await User.existLogin(req.body.login);
const isPassword = await User.isPassword(user.dataValues.password, req.body.password);

或者比较这些示例的大括号和空格的用法:

代码语言:javascript
复制
if(!token) return res.status(401).json('Unauthorized');
if (!user) { return res.status(400).json({result: 'Login is wrong '});}
if(!user){
    return res.status(404).json('User not Found');
}

还比较以下示例中换行符和缩进级别的用法:

代码语言:javascript
复制
User.create({
    name, email, login, password }).then(result => {
    res.status(201).json({Results: result.dataValues})
})
return jwt.sign(payload,
    config.secretToken
           )
return {
    sub: usuario.id,
    // ....
    exp: moment().add(10, 'minutes').unix()
}

所有这一切都是说:选择一种风格,并坚持它。无论您选择哪种样式,如果样式是一致的,就更容易阅读。

就我个人而言,在大多数情况下,我更喜欢空间比你在这里展示的更多的风格。

缩进:

您正在使用一种奇怪的缩进样式组合,并且大量使用早期返回,除非在一些我不理解的小例子中。我个人更喜欢在请求处理程序中尽早返回,如果有更复杂的逻辑,我会考虑将其提取到一个单独的函数中。它产生的代码非常类似于以下内容:

代码语言:javascript
复制
function addUsers(req, res) {
    const name = req.body.name;
    const email = req.body.email;
    const login = req.body.login;

    const exists = await User.existLogin(login);
    if (exists) {
        return res.status(409).json({ message: 'Login already exists' });
    }

    const password = bcrypt.hashSync(req.body.password, 10);
    const created = User.create({ name, email, login, password });
    res.status(201).json({ results: created.dataValue });
}

请注意,我删除了awaithashSync的使用(应该清楚原因)。还请注意,我在返回的JSON结果中对成员results进行了小写。

显然,这并不像问题中的代码那样具有相同的错误行为,但它很好地展示了如何避免深度嵌套块。

HTTP / web标准授权模式

作为次要的一点,我想补充一点,这里显示的auth中间件并不完全遵循常见的头授权模式。它缺少一个指示预期授权类型的响应头。由于您在这里使用令牌,通常头将是'WWW-Authenticate: "Bearer"',但这意味着预期的Authorization头应该以"Bearer"开头,而这里的情况并非如此。

变得更..。我希望有一个正确的承载令牌认证方案来具体定义该方案中使用的授权类型。一个选项可以是显式地将jwt-令牌指定为类型,从而生成以下标题:

代码语言:javascript
复制
'WWW-Authenticate: "jwt-token"'
---
'Authorization: "jwt-token <jwt_token_goes_here>"'

请注意,这个建议当然需要调整获取令牌的方式,添加另一种请求可能格式错误的方式:)

结论:

总之,这是一个坚实的开端,要将这段代码提升到下一个级别,只需要一些调整,主要是围绕着代码本身的结构如何保持一致。

做得好:)

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/232617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档