0

在一个反应​​应用程序中,我需要访问 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();
    };

但是,这样做有几个问题:

  1. 密码成员(如CredentialContainer.create()页面上记录的那样,Typescript 不知道。我使用 any cast 解决了这个问题。返回的凭据是一个PasswordCredential结构,内容看起来不错。
  2. 存储凭据时,将采用成功分支,但承诺值为空。不确定这是否相关。
  3. 当我打电话时,navigator.credentials.get我永远不会得到任何凭证。事实上,我并不感到惊讶。难道不需要传入 id 和用户名来查找凭据吗?但是 API 不允许这样做。

那么,这里的正确方法是什么?

4

0 回答 0