在一个反应应用程序中,我需要访问 MySQL 服务器,为此我需要用户的凭据。为了避免每次打开连接时让用户输入它们,我想将密码存储在浏览器的密码存储/管理器中。
根据 MDN,所有主流浏览器都应该支持Credentials Management API。所以我这样尝试:
private requestPassword = (commandId: string, args?: any[]): void => {
if (args && args.length > 0) {
// First check if we already have a password and don't ask for it, if so.
const request: IServicePasswordRequest = args[0];
navigator.credentials.get({
password: true,
mediation: "silent",
} as any).then((credential) => {
if (credential) {
const id = 0;
} else {
// Opens the password dialog.
this.setState({ request }, () => this.dialogRef.current?.open());
}
});
}
};
private closePanel = (e: React.SyntheticEvent, props: IButtonProperties): void => {
// Called when either OK or Cancel was clicked by the user, in the password dialog.
if (props.id === "ok") {
const { request } = this.state;
const options = {
password: {
id: request!.serviceId,
name: request!.user,
password: "root", // Just for test.
},
};
navigator.credentials.create(options as any).then((credential) => {
if (credential) {
navigator.credentials.store(credential).then((value) => {
console.log("Success: " + value);
}).catch((e) => {
console.log("Error: " + e);
});
}
});
}
this.dialogRef.current?.close();
};
但是,这样做有几个问题:
- 密码成员(如CredentialContainer.create()页面上记录的那样,Typescript 不知道。我使用 any cast 解决了这个问题。返回的凭据是一个
PasswordCredential
结构,内容看起来不错。 - 存储凭据时,将采用成功分支,但承诺值为空。不确定这是否相关。
- 当我打电话时,
navigator.credentials.get
我永远不会得到任何凭证。事实上,我并不感到惊讶。难道不需要传入 id 和用户名来查找凭据吗?但是 API 不允许这样做。
那么,这里的正确方法是什么?