嗨,我正在尝试使用 whoop api 进行登录,目前他们使用护照和 OAuth2.0,但当我在回调端点中执行 Passport.authenticate 时,它似乎给了我一个错误。 这是我的 User.js 路线
const express = require('express')
const app = express()
const passport = require('passport')
const OAuth2Strategy = require('passport-oauth2')
const User = require('../Models/User')
require('dotenv').config()
const whoopOAuthConfig = {
authorizationURL: `${process.env.WHOOP_API_HOSTNAME}/oauth/oauth2/auth`,
tokenURL: `${process.env.WHOOP_API_HOSTNAME}/oauth/oauth2/token`,
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: process.env.CALLBACK_URL,
state: true,
scope: [
'offline',
'read:profile',
'read:recovery',
'read:cycles',
'read:sleep',
'read:workout',
'read:body_measurement'
],
}
async function getUser(
accessToken,
refreshToken,
{expires_in},
profile,
done,
){
console.log(profile)
const {first_name, last_name, user_id} = profile
const user = await User.findOne({userId: user_id})
if (user) {
user.acessToken = accessToken
user.refreshToken = refreshToken
user.expiresIn = Date.now() + expires_in * 1000
user.firstName = first_name
user.lastName = last_name
user.userId = user_id
await user.save()
done(err, user)
} else{
const newUser = new User({
acessToken: accessToken,
refreshToken: refreshToken,
expiresIn: Date.now() + expires_in * 1000,
firstName: first_name,
lastName: last_name,
userId: user_id,
})
done(err, newUser)
}
}
async function fetchProfile(
accessToken,
done,
){
console.log(accessToken)
const profileResponse = await fetch(
`${process.env.WHOOP_API_HOSTNAME}/developer/v1/user/profile/basic`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
},
)
const profile = await profileResponse.json()
done(err, profile)
}
const whoopAuthorizationStrategy = new OAuth2Strategy(whoopOAuthConfig, getUser)
whoopAuthorizationStrategy.userProfile = fetchProfile
passport.use('oauth2', whoopAuthorizationStrategy)
var printSometing = function(req, res, next) {
console.log("I'm still here");
return next();
}
app.get('/auth/performance',
passport.authenticate('oauth2'));
app.get('/auth/performance/callback',
passport.authenticate('oauth2', {failureRedirect: '/', failureMessage: true }),
printSometing, function (req, res) {
res.redirect('http://localhost:3000/');
});
module.exports = app;
这是我的index.js
const express = require('express')
const app = express()
const port = 8081
const cors = require('cors')
const session = require('express-session')
const mongoose = require('mongoose')
require('dotenv').config()
var bodyParser = require( 'body-parser' );
const passport = require('passport')
mongoose.connect(process.env.MONGO_URI)
const database = mongoose.connection;
database.on('error', console.error.bind(console, 'connection error:'));
database.once('connected', function() {
console.log("Connected to MongoDB")
});
app.get('/', (req, res) => {
res.send({msg: 'Hello World!'})
})
app.use(session({secret: process.env.CLIENT_SECRET, resave: true, saveUninitialized: true}))
app.use(express.urlencoded({ extended: false }));
app.use(bodyParser.json({ limit: '10mb' }));
app.use(bodyParser.urlencoded({ extended: true, limit: '10mb' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(cors());
app.use('/api', require('./routes/user.js'));
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
我按照 Whoop 的 API 文档进行操作,但没有成功,尝试更改密钥和 api 密钥并在线研究。
在添加特定 API(例如 Passport)的复杂性之前,尝试使用石头和棍子进行身份验证可能会有所帮助。我的意思是,当然,使用浏览器和“curl”,一个命令行工具。
OAuth2 建立在 HTTPS“GET”和“PUT”之上,这实际上非常简单:(1) 在浏览器中输入一个“GET”,让 Whoop 询问用户名和密码,以及 (2) 从浏览器中输入一个“PUT”卷曲要求 Whoop 给你访问令牌。
这里有一个链接,清楚地展示了如何执行此操作:https://backstage.forgerock.com/knowledge/kb/article/a45882528(“如何使用curl命令执行常见的OAuth 2.0任务...”)
我还发现阅读 OAuth2.0 规范很有帮助,您可以在这里找到该规范:https://datatracker.ietf.org/doc/html/rfc6749。 (我说“有帮助”,但不一定无痛!:-)