我正在使用NodeJS和Flutter 开发一个完整的堆栈应用程序,目前我还不知道如何使安全cookie/令牌会话。
我需要的答案是,如何像其他社交网络或堆栈溢出本身一样,为Web制作一个带有颤振的身份验证系统。
发布于 2021-03-11 12:04:15
这是一个老问题,但选择的答案并不完全安全。对于网络来说,使用web存储对敏感信息是不安全的。
你应该用纯http的饼干。Http-只有cookie不能通过Javascript读取,但浏览器会自动将其发送到后端。
这里是Nodejs-速成码的例子;
在这个例子中,有两个cookie,一个是纯http的,另一个不是。非http-纯cookie是用于签入的情况,如果它的有效客户端假定用户已登录。但是实际的控制是由后端完成的。
PS:没有必要存储或发送任何令牌,因为浏览器会自动处理它(Cookie)。
const cookieConfig = {
httpOnly: true,
secure,
maxAge: 30 * 24 * 60 * 60 * 1000,
signed: secure,
}
const cookieConfigReadable = {
httpOnly: false,
secure,
maxAge: 30 * 24 * 60 * 60 * 1000,
signed: secure,
}
function signToken(unsignedToken: any) {
const token = jwt.sign(unsignedToken, privatekey, {
algorithm: 'HS256',
expiresIn: jwtExpirySeconds,
})
return token
}
const tokenObj = {
UID: userId,
SID: sessionId,
}
const token = signToken(tokenObj)
// sets session info to the http-only cookie
res.cookie('HSINF', token, cookieConfig)
// sets a cookie with expires=false value for client side check.
res.cookie('expired', false, cookieConfigReadable) 但是在这种方法中,在调试过程中会遇到一个挑战,因为NodeJS和Flutter服务于不同的端口,因此您应该允许用于dev环境的CORS。
if (process.env.NODE_ENV === 'dev') {
app.use(
cors({
origin: [
'http://localhost:8080',
'http://127.0.0.1:8080',
],
credentials: true,
}),
)
}而且,在Flutter中,您不能在调试期间直接使用http.get或http.post,因为默认情况下,颤振会禁用CORS cookie。
这里有一个解决办法。
// withCredentials = true is the magic
var client = BrowserClient()..withCredentials = true;
http.Response response;
try {
response = await client.get(
Uri.parse(url),
headers: allHeaders,
);
} finally {
client.close();
}在调试过程中还有另一个挑战:许多浏览器不允许本地主机使用cookie,您应该使用127.0.0.1。然而,Flutter只运行于特定的url和特定的端口,下面是我在127.0.0.1上运行的颤振的VsCode配置
{
"name": "project",
"request": "launch",
"type": "dart",
"program": "lib/main.dart",
"args": [
"-d",
"chrome",
"--web-port",
"8080",
"--web-hostname",
"127.0.0.1"
]
}这些是用来设置和传输cookie的,下面您可以找到我的后端cookie检查。
const httpOnlyCookie = req.signedCookies.HSINF
const normalCookie = req.signedCookies.expired
if (httpOnlyCookie && normalCookie === 'false') {
token = httpOnlyCookie
}
if (token) {
let decoded: any = null
try {
decoded = jwt.verify(token, privatekey)
} catch (ex) {
Logger.error(null, ex.message)
}
if (decoded) {
//Cookie is valid, get user with the session id
}
}发布于 2019-11-23 07:13:55
直接导入dart.html不支持Flasher1.9:参考文献
在深入研究解决方案时,我偶然看到了包html,它对我来说很好。下面是我的助手类,用于在web上本地存储键值对:
import 'package:universal_html/prefer_universal/html.dart';
class WebStorage {
//Singleton
WebStorage._internal();
static final WebStorage instance = WebStorage._internal();
factory WebStorage() {
return instance;
}
String get sessionId => window.localStorage['SessionId'];
set sessionId(String sid) => (sid == null) ? window.localStorage.remove('SessionId') : window.localStorage['SessionId'] = sid;
}去读,
WebStorage.instance.sessionId;
写,
WebStorage.instance.sessionId =“您的证书”;
示例:
fetchPost(params, "CMD_USERREGISTRATION").then((result) {
...
APIResponse response = APIResponse(xmlString: result.body);
if (!response.isSuccess()) {
...
return;
}
var sid = response.getSessionId();
if (kIsWeb) {
WebStorage.instance.sessionId = sid;
}
}main.dart:
@override
Widget build(BuildContext context) {
if (kIsWeb) {
isLogin = WebStorage.instance.sessionId != null;
} else {
isLogin = //check from SharedPreferences;
}
return isLogin ? dashboardPage() : loginPage();
}更新:
发布于 2022-02-14 01:55:38
您可以根据需要对其进行加密,然后使用getStorage存储它&它支持所有平台,例如:
GetStorage box = GetStorage();写出来:
box.write('jwt', 'value');读一读:
if (box.hasData('jwt')) {
box.read('jwt');
}https://stackoverflow.com/questions/57577071
复制相似问题