我使用MERN堆栈和PassportJs开发了一个用于身份验证的应用程序。我使用了Google策略来允许用户身份验证,但是我面临着一些问题。
以下是控制台中出现的错误:
访问从源“https://tagsite.herokuapp.com/users/google”获取'https://tagsite.netlify.app‘已被CORS策略阻止:对飞行前请求的响应不通过访问控制检查:请求的资源上不存在“访问控制-允许-原产地”标题。如果不透明响应满足您的需要,请将请求的模式设置为“no- CORS”,以获取禁用CORS的资源。https://tagsite.herokuapp.com/users/google net::ERR_FAILED
我怎么才能修好它?请帮帮忙。
我已经在后端使用了cors包,但是仍然有相同的错误。
这是我的密码。
后端
app.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const passport = require('passport');
const serverless = require('serverless-http');
if (process.env.NODE_END !== 'production') {
// Load environment variables from .env file for non production environment
require('dotenv').config()
}
// Connect database
require('./utils/connectdb')
// Strategies
require('./strategies/GoogleStrategy')
require('./utils/authenticate')
// Routes import
const userRoutes = require('./routes/user')
const app = express();
app.use(bodyParser.json())
app.use(cookieParser(process.env.COOKIE_SECRET))
app.use(cors())
app.use(passport.initialize())
// Use routes
app.use('/users', userRoutes)
app.get('/', (req, res) => {
res.send({ status: 'success' })
})
// Server set up
let port;
if (process.env.PORT) {
port = process.env.PORT
} else {
port = 8000
}
app.listen(port, () => {
console.log('Listen on port: ' + port)
})
module.exports.handler = serverless(app)
GoogleStrategy.js
const passport = require('passport')
const googleStrategy = require('passport-google-oauth20').Strategy
const User = require('../models/user')
const slug = require('slug')
require('dotenv').config()
// serialize & deserialize user
passport.serializeUser((user, done) => {
done(null, user.id)
// done(null, user)
})
passport.deserializeUser((id, done) => {
User.findById(id)
.then((user) => {
done(null, user)
})
// done(null, user)
})
passport.use(
new googleStrategy(
{
clientID: process.env.GOOGLE_APP_ID,
clientSecret: process.env.GOOGLE_APP_SECRET,
callbackURL: process.env.GOOGLE_APP_CALLBACK_URL
},
(accessToken, refreshToken, profile, done) => {
User.findOne({ providerId: profile.id })
.then((user) => {
if (user) {
const userData = {
username: profile.displayName,
provider: profile.provider,
providerId: profile.id,
email: profile.emails[0].value,
avatar: profile._json.picture
&& profile._json.picture,
token: accessToken,
slug: slug(profile.displayName)
}
user.refreshToken.push({ refreshToken: accessToken })
user.save()
done(null, userData)
} else {
new User({
username: profile.displayName,
provider: profile.provider,
providerId: profile.id,
email: profile.emails[0].value,
avatar: profile._json.picture
&& profile._json.picture,
$addToSet: { refreshToken: accessToken },
slug: slug(profile.displayName)
})
.save()
.then((user) => {
const userData = {
username: profile.displayName,
provider: profile.provider,
providerId: profile.id,
email: profile.emails[0].value,
avatar: profile._json.picture
&& profile._json.picture,
token: accessToken,
slug: slug(profile.displayName)
}
user.refreshToken.push({ refreshToken: accessToken })
user.save()
done(null, userData)
})
.catch((error) => {
console.log(`create new user failed: ${error}`)
})
}
})
}
)
)
user.js (控制器)
const passport = require('passport');
module.exports = {
googleLogin: [
passport.authenticate('google', { scope: ['profile', 'email'] })
],
googleLoginCallback : [
passport.authenticate('google', {
failureRedirect: process.env.AUTH_FAILURE_REDIRECT_URL,
session: false
}),
(req, res, next) => {
const token = req.user.token
// res.status(200).json({userData: req.user})
res.cookie('refreshToken', req.user.token, COOKIE_OPTIONS)
res.send({ success: true, token })
}
],
user.js (路线)
const router = require('express').Router()
// Controllers
const {
googleLogin, googleLoginCallback
} = require('../controllers/user')
router.get('/google', googleLogin)
router.get('/google/callback', googleLoginCallback)
module.exports = router
前端
google.js (组件)
import { Button, Callout } from '@blueprintjs/core'
import React, { useContext, useState } from 'react'
import { UserContext } from '../../utils/context/UserContext'
const GoogleLogin = () => {
const [error, setError] = useState(null)
const [userContext, setUserContext] = useContext(UserContext)
const loginGoogle = () => {
setError(null)
const genericErrorMessage = 'Something error'
fetch(`${process.env.REACT_APP_API_URL}/users/google`, {
method: 'GET',
// credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
})
.then(async (res) => {
if (!res.ok) {
if (res.status === 400) {
setError('Please try again')
} else if (res.status === 401) {
setError('Unauthorized')
} else {
setError(genericErrorMessage)
}
} else {
const data = await res.json()
setUserContext((oldValues) => {
return { ...oldValues, token: data.token }
})
}
})
.catch((err) => {
setError(genericErrorMessage)
})
}
return (
<>
{error && <Callout intent="danger">{error}</Callout>}
<Button text="login with google" onClick={loginGoogle} />
</>
)
}
export default GoogleLogin
发布于 2022-02-17 08:08:55
app.use(
cors({
origin: [
"https://tagsite.netlify.app"
],
credentials: true,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
})
);
就像你说的那样,CORS不喜欢你的前端代码。它不知道。你必须把你的前端介绍给你的后端,并告诉你的后端让特定的来源访问你的服务器。
我没有足够的经验,你是否必须包括证书,但它对我有用!
https://stackoverflow.com/questions/71147129
复制相似问题