【发布时间】:2020-08-23 18:01:32
【问题描述】:
我正在尝试完成 oauth-1 握手。我的后端托管在 Google Functions 上。我将快速浏览整个流程以了解上下文:
- 用户在前端单击以将 Etsy 连接添加到我的应用程序。然后,我的前端会联系后端中的适当端点以启动此过程。
- 我的后端从 Etsy 请求一个令牌,我收到一个令牌、一个密码和一个 URL 以将用户重定向到以便他们可以登录。我尝试将令牌和密码存储在会话 cookie 中以供以后使用 - - 因为我使用的是谷歌函数,后端本身并没有“持久化”,所以我试图存储这些值,以便在下一个执行/阶段检索。 (注意:在请求令牌时,我提供了一个回调 URL,将在用户登录时联系。)
- 我的前端收到来自第 2 步的 url 并将用户重定向到那里登录。
- 用户通过该登录进行批准,并调用回调 URL。这包括验证者。然后,我必须使用验证程序以及步骤 2 中的令牌和密钥获取 accessToken。虽然我认为这些将在会话中检索,但它们都未定义,因此我对 accessToken 的请求失败。
在我看来,每次调用都会创建一个新会话,无论是否已经存在会话。如果我在第 1 步和第 2 步检查会话,它们上的时间戳是不同的,这让我认为,不是从第 1 步检索会话,而是第 2 步正在创建一个新会话——这很可能是因为我如何我在做app.use(session)。
我正在使用的技术列表:
- node.js
- 快递
- 快速会话
- firebase 功能
- connect-session-firebase(也尝试过 firestore-store,对下面的代码稍作调整以匹配其基本设置。)
这是我的后端实现:
const url = require('url');
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require("express");
const app = express();
const cors = require("cors")
const session = require('express-session')
const FirebaseStore = require('connect-session-firebase')(session);
// Etsy OAuth
// For Etsy OAuth
const etsyjs = require('etsy-js');
const client = etsyjs.client({
key: process.env.ETSY_KEY,
secret: process.env.ESTY_SECRET,
callbackURL: '<location>/authorize'
});
const ref = admin.initializeApp({
credential: admin.credential.cert(json), //json retrieved and put here
databaseURL: 'https://<app>.firebaseio.com'
});
app.use(cors())
app.use(session({
store: new FirebaseStore({
database: ref.database(),
}),
secret: 'My secret',
resave: true,
saveUninitialized: true,
name: '__session',
cookie: {
maxAge : 60000,
secure: false,
httpOnly: false
}
}
));
// Step 1 for backend of OAuth
app.get('/begin-oauth', (req, res) => {
res.setHeader('Cache-Control', 'private'); // I read somewhere this needs to be set, but I am not seeing a difference either way with it.
return client.requestToken((err, response) => {
if (err) {
return console.log(err);
}
req.session.token = response.token;
req.session.sec = response.tokenSecret;
res.status('200').send(response) // returning url to send the user there via frontend.
});
});
// Step 2 for backend of OAuth
app.get('/authorize', (req, res) => {
let query, verifier;
query = url.parse(req.url, true).query;
verifier = query.oauth_verifier;
// session at this point should have token and sec stored from before but are not present.
return client.accessToken(req.session.token, req.session.sec, verifier, (err, response) => {
if (err) {
console.log(err);
}
req.session.token = response.token;
req.session.sec = response.tokenSecret;
// Finish up.
});
});
【问题讨论】:
-
来自文档
Note Session data is not saved in the cookie itself, just the session ID. Session data is **stored server-side**.github.com/expressjs/session#readme 所以可能不要使用快速会话。自己发送cookie给客户端。
标签: node.js firebase express google-cloud-functions express-session