janezpodhostnik / flow-py-sdk

Unofficial flow blockchain python sdk
MIT License
35 stars 26 forks source link

Example for account authentication #36

Closed oeway closed 2 years ago

oeway commented 2 years ago

Hi, I am trying to use flow-py-sdk on a python backend to authenticate the user account. This is the official example I am following but it assumes the backend also use the js/node version of the client: https://docs.onflow.org/fcl/reference/proving-authentication/#proving-user-authentication-using-user-signature

Could you please provide some hints on how to translate that in using flow-py-sdk? Or is it possible at all?

janezpodhostnik commented 2 years ago

I'm not 100% sure what you need, but would this help: https://github.com/janezpodhostnik/flow-py-sdk/pull/37?

So a way to check user signatures are correct.

I can add an example on how to check user signatures on-chain if you would prefer that.

oeway commented 2 years ago

Hi, sorry for not being clear. So the idea is that the backend will generate an authentication code which will send to the frontend. Then the frontend will take the authentication code and sign it: 'const CompositeSignatures = await fcl.currentUser().signUserMessage(AuthCodeMessage)'. This CompositeSignatures will then be passed to the backend so the backend can verify that message (as a way to prove the user actually own that account). The js version is like this:

fcl.verifyUserSignature( AuthCodeMessage, CompositeSignatures )

So I am wondering how we can do that with your python module. Did your example already achieve this? Also, can the backend verify a signed message off-chain?

janezpodhostnik commented 2 years ago

My problem is I am not that familiar with fcl.verifyUserSignature, I will have to look into that.

The example I put in the PR is an off-chain verification. From what I understand from your description, when the signed AuthCodeMessage is returned to the backend, you can use verifier.verify_user_message(message, signature) to verify it. This does assume that you know the public key of the user/account.

If you want to use an accounts public key (that you don't have) you can get it from the chain. However if you are already calling the chain to get the public keys, you might as well just use a script to send the message on-chain and verify it there. I will add that example tomorrow, or later today.

oeway commented 2 years ago

Great! Examples will be great! I am not familiar with flow, could you show both how to get the public key, and run verification script on chain? I guess the difference is that if we can do off chain verification it means we can do it more often and faster, while on chain verification will be convenient for one-time verification.

Thanks a lot!

Another minor suggestion, maybe change verifier.verify_user_message to verifier.verify_user_signature to keep consistent with the name in JS?

janezpodhostnik commented 2 years ago

@oeway I checked out what fcl.verifyUserSignature user signature does.

It basically calls a cadence script that gets the public keys of the account and uses them to verify all of the signatures (because accounts can have multiple keys).

My goal now is to make a method in the flow-py-sdk that is directly compatible with the result of fcl.currentUser().signUserMessage(AuthCodeMessage) and does essentially the same thing. I will include an example.

oeway commented 2 years ago

Hi, that sounds great! Looking forward to your example!

janezpodhostnik commented 2 years ago

Should be good now, let me know if anything is unclear or if you have problems using it.

oeway commented 2 years ago

@janezpodhostnik Is there a way to only verify the user signature on-chain for the first time and later use the cached key to do verification off-chain? I am trying to use flow signature as a replacement for JWT token, so I would like to make it faster to verify the signature off-chain.

davit555 commented 1 year ago

Hey Guys

I stuck with the similar issue

in node js version

there is an existing helper function

import { AppUtils } from "@onflow/fcl" const isValid = await AppUtils.verifyAccountProof( appIdentifier, accountProofData )

Wondering what is the equivalent version in python SDK?