Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to authenticate a logged in user in web2 backend? #459

Closed
lebedev opened this issue Sep 15, 2022 · 11 comments
Closed

How to authenticate a logged in user in web2 backend? #459

lebedev opened this issue Sep 15, 2022 · 11 comments
Labels
enhancement New feature or request

Comments

@lebedev
Copy link

lebedev commented Sep 15, 2022

I want to have a way identify a dApp user in web2 backend. I need that to store some user input off-chain. Like a name, last name or email provided by the user. So I want authenticate the user first before storing data related to them.

With near-api-js it was possible by doing the following. Upon logging in with near-api-js, the private part of a Function Call key was stored in a user's browser LocalStorage. That allowed to sign an arbitrary message that was passed to web2 backend and verified using the user's public part of the same Function Call key. If the user can sign a message and it's verifiable by using one of their public keys, then the user is authenticated.

Is it possible to do something like this with wallet-selector? At first glance, it isn't. I sure hope that there's some mechanism that can be used for authenticating users with web2 services to store data off-chain.

Also is there a way to execute call methods with 0 deposit without triggering wallets each time? Like changing numbers in rust counter example? It seems that with wallets like Sender it isn't possible?

@lebedev lebedev added the enhancement New feature or request label Sep 15, 2022
@lebedev
Copy link
Author

lebedev commented Sep 15, 2022

Relates to #318

@amirsaran3
Copy link
Collaborator

amirsaran3 commented Sep 19, 2022

Hey @lebedev ,

Currently we have the verifyOwner function that you can use (#391). Not all the wallets support this feature correctly. We are currently working on a NEP to standardize this functionality across all wallets.

For immediately executing transactions with no deposit you can contact the Sender team.

@lebedev
Copy link
Author

lebedev commented Sep 20, 2022

@amirsaran3 can you help me figuring out how to consume a response from verifyOwner, please?

I logged in NEAR Guest Book with MyNearWallet and called verifyOwner.

The code I used follows (with verifyOwner response). I wasn't able to successfully verify the signature, so I wonder how one verifies it. Any ideas? 🤔

const { utils } = require('near-api-js');
const bs58 = require('bs58');

const verifyOwnerResponse = {
  "accountId": "lebedev.testnet",
  "message": "test message for verification",
  "blockId": "96rMG1RiumcXpCWMY4r52kd1g2oJhmUmAVsyBBStEz2d",
  "publicKey": "gS7tz7cflNLnbk3RvfzJENfpQt3p1bIq/aLh3wbZWEo=",
  "signature": "KxWnqSRMM1OR14939LweLMdX8I2Vwh+BXCkmfJrR9w3BhmhwHEqrYvDedyHhP89y7OqBFCTT6Awlp5CRo4vWBA==",
}

const key58 = bs58.encode(Buffer.from(verifyOwnerResponse.publicKey, 'base64url'));

const key = utils.PublicKey.from(key58);

const message = Buffer.from(verifyOwnerResponse.message, 'utf-8');

const signature = Buffer.from(verifyOwnerResponse.signature, 'base64url');

const verified = key.verify(message, signature);

console.log('verified? ', verified); // false (why?)

@lebedev
Copy link
Author

lebedev commented Sep 20, 2022

An update. I've tried verifying signatures against all of my account keys, but none of them worked. Maybe I decode signature from base64 to Uint8Array incorrectly? 😞

Where do I find the code that code this? for Sender wallet in particular. Maybe a message gets encoded an a peculiar way or something.

@lebedev
Copy link
Author

lebedev commented Sep 20, 2022

Another update. So I opened https://testnet.mynearwallet.com site, find the private key for the corresponding public key from verifyOwner response, signed the same message with it and got different signature, which I can successfully verify. So I'd like to check signature generation code to be sure that it generates correct signatures.

@amirsaran3
Copy link
Collaborator

@lebedev Maybe this comment can help. #434 (comment)

@amirsaran3
Copy link
Collaborator

@lebedev This is what worked for me.

const signature =
      "KxWnqSRMM1OR14939LweLMdX8I2Vwh+BXCkmfJrR9w3BhmhwHEqrYvDedyHhP89y7OqBFCTT6Awlp5CRo4vWBA==";

    const owner = {
      accountId: "lebedev.testnet",
      message: "test message for verification",
      blockId: "96rMG1RiumcXpCWMY4r52kd1g2oJhmUmAVsyBBStEz2d",
      publicKey: "gS7tz7cflNLnbk3RvfzJENfpQt3p1bIq/aLh3wbZWEo=",
      keyType: 0,
    };

    const publicKeyString = `ed25519:${bs58.encode(
      Buffer.from(owner.publicKey, "base64")
    )}`;

    const createdPublicKey = utils.PublicKey.from(publicKeyString);

    const stringified = JSON.stringify(owner);

    const verifiedSignature = createdPublicKey.verify(
      new Uint8Array(sha256.array(stringified)),
      Buffer.from(signature, "base64")
    );

    console.log("verified? ", verifiedSignature); // true

@lebedev
Copy link
Author

lebedev commented Sep 22, 2022

@amirsaran3 Thanks! This works indeed. However, this way of verifying includes several non-obvious steps. I naively thought that a signature was for a message itself, however it's actually a signature for sha256-hash of that stringified object. Do you mind if I create a PR with verification code and detailed explanations of verifyOwner response?

@amirsaran3
Copy link
Collaborator

@lebedev We are currently working on the verifyOwner function functionality and NEP. We will probably add more information about it when we are done.

@lebedev
Copy link
Author

lebedev commented Sep 23, 2022

@amirsaran3 Is there a place where I can watch for updates about this? Maybe a NEP is created already and you can provide a link? I'd like to use this functionality right now and it would be convenient if I can see updates to adjust my code accordingly.

@AmmarHumackicSQA
Copy link
Contributor

Hey @lebedev , the NEP is not created yet, we should have more info to share next week. It will be added here: https://github.com/near/NEPs/pulls

We will keep you posted.

If there are no other questions, for now, I think we can close this issue. Thanks!

@lebedev lebedev closed this as completed Sep 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants