身份验证(JWT)在本地有效,但在 Heroku 无效?

Posted

技术标签:

【中文标题】身份验证(JWT)在本地有效,但在 Heroku 无效?【英文标题】:Authentication (JWT) works in local but not in Heroku? 【发布时间】:2022-01-18 03:32:19 【问题描述】:

我有一个在 MEVN 堆栈中构建的项目,可以在本地正常工作,我在 Heroku 中成功部署了我的后端,并使用 Postman 对其进行了测试,一切正常,但是当我尝试使用我的客户端(本地)登录时,我有一个“GET https://invoicing-wmb.herokuapp.com/api/user401(未经授权)”。知道有什么问题吗?...

此外,我一直在使用 console.log("") 进行测试,并且代码在用户中的这一行之前一直有效:

const claims = jwt.verify(cookie, 'secret')

注意:唯一不起作用的是用户身份验证,其他一切正常。

这是后端的mi index.js。

const express = require('express')
const mongoose = require('mongoose')
const cors = require('cors')
const cookieParser = require('cookie-parser')
mongoose.set('useCreateIndex', true)

mongoose.connect('mongodb+srv://markselin:PASSWORD123@cluster0.uaau3.mongodb.net/myFirstDatabase?retryWrites=true&w=majority', 

    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true
, () => 
    console.log('connected to the database')
)

const routes = require('./routes/routes')

app = express()

app.use(cookieParser())
app.use(cors(

    credentials: true,
 
    origin: ['https://invoicing-wmb.herokuapp.com', 'http://localhost:8080'] //CLOUD
))


app.use(express.json())

app.use('/api', routes)

//testing main /
app.get('/', function(peticion, respuesta)
    respuesta.send('WECOME TO OUR API [WBM]')
)
app.get('/api', function(peticion, respuesta)
    respuesta.send('INVOICING API [WMB]')
)


app.listen(process.env.PORT || 8000)

这是我在 router.js 中的用户

router.get('/user', async (req, res) => 

    try 
        
        
        const cookie = req.cookies['jwt']
        

        const claims = jwt.verify(cookie, 'secret')
        
        if (!claims) 

            res.send(message:'NO AUTENTICADO')
        
        
        const user = await User.findOne(_id: claims._id)
        
        const pass, ...data = await user.toJSON()
        console.log('AUTENTICADO'+data)
        res.json(data)
     catch (e) 
        return res.status(401).send(
            message: 'unauthenticated'
        )
    
)

客户端登录方式

  methods: 
    
    async handleSubmit() 

      try 
 
        const respons = await axios.post("login", 
         
          email: this.email,
          pass: this.pass,
        );

     
        localStorage.setItem("token", respons.data.token);
      
      
        const response = await axios.get("user");
         
     
        this.$store.dispatch("user", response.data);
       

        this.$router.push(name:'Inicio')
       catch (e) 
        console.log(e)
       
      
    ,

和 axios.js

import axios from 'axios'
    axios.defaults.baseURL = 'https://invoicing-wmb.herokuapp.com/api/'     //CLOUD
    axios.defaults.headers.common['Authorization'] = 'Bearer' + localStorage.getItem('token')
    axios.defaults.withCredentials = true;

最后这是我尝试登录时来自 Heroku 的日志

【问题讨论】:

如果那是您实际的 MongoDB 连接 URI,请将其更改为 [redacted] 或其他名称。 不,不是???但感谢您的推荐。 【参考方案1】:

您似乎正在使用 cookie 来保存用户的令牌。我的猜测是由于域混淆而没有发送cookie。当您在 localhost 上对其进行测试时,您的前端和后端的域是相同的,因此 cookie 可以工作。当您在邮递员中进行测试时,您可能会直接发送令牌,或者手动设置 cookie,这样也可以正常工作。进入浏览器后,它会限制哪些网站可以使用哪些 cookie。

您必须检查您的 cookie 当前具有哪些属性。例如。是否使用了 secure 标志,您是否使用 https 连接?最重要的是查看Same-Site 属性,因为在您的情况下它应该设置为laxnone。另一种选择是在同一个域上运行前端和后端。

【讨论】:

我添加了 sameSite: 'none' 现在我可以进入但 jwt 仍然不生成。并且使用'lax'我得到一个“GET invoicing-wmb.herokuapp.com/api/user401(未经授权)我有这个属性:sameSite:'none'httpOnly:truesecure:true,//https仅maxAge:24 * 60 * 60 * 1000 // 1天

以上是关于身份验证(JWT)在本地有效,但在 Heroku 无效?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Heroku 服务器上为 Laravel JWT 身份验证收到此错误

Heroku上的现有Ruby on Rails Web应用程序(PostgreSQL),Devise身份验证,需要为移动支持添加Rails API

Rails API 422 无法处理的实体:没有可用的验证密钥,heroku

Laravel Tymon\JWT Auth:在身份验证之前检查未完成的有效令牌?

如何验证请求标头、JWT 令牌

使用有效的 JWT 令牌调用经过 keycloak 身份验证的 API