Web3 authentication on Solana using Python⚡
Tags: solana, web3, python, beginners
Published: 2022-02-13 18:28:52

So you want to implement authentication in your Python backend in Web3 style? Well, you are in the right place! I'll try my best to explain the whole Web3 authentication process and how you can implement it using Python on your Solana dApp.

# How does Web3 authentication work?
Like Web2, there are many authentication methods in Web3 as well, since Web3 is in it's early stages, there isn't any "official" or approved authentication system. Developers have implemented authentication in their dApps using very smart methods, the one we are going to see today is very easy yet effective way to achieve it. The image below gives a rough idea of how the process looks like.

![Web3 authentication](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btfvql3ibgja0rnkk8ph.png)
1. User does any action which requires authentication, for example updating their on chain profile.
2. Using [@solana/web3.js](https://solana-labs.github.io/solana-web3.js/) or vanilla JavaScript, we will ask the user to sign a message through their wallet in the frontend; the message can be their public key itself to keep things simpler.
3. After a user signs the message, just like Web2, we can send the authentication information through headers; for this we would need to send both the public key and signature to authorize the user.
4. Using a signature decoding function, we will verify whether the signature received is signed by the public key or not.
5. If the signature is valid, we will run the auth-related action, which is updating the profile in this case.
6. After that, just like [JWT tokens](https://jwt.io) we can store the signature in localStorage for future use, so that a user won't need to sign the message each time when they perform any auth-related action.

# Python implementation
I'll be using [FastAPI](https://fastapi.tiangolo.com/) as my backend framework for this implementation, however you can do this in pretty much any framework. First of all, let's install FastAPI and [Solathon](https://solathon.vercel.app), which is an easy to use and feature rich SDK for Solana in Python
```bash
pip install solathon && pip install fastapi
```
Now, create a `main.py` file and add the following code to initialize a FastAPI application:
```python
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def root() -> None:
    return {"message": "Web3 rocks!"}
```
Now let's create a simple API which returns our public key if the signature is valid, we will pass it for now:
```python
@app.get("/verify_signature")
def verify_signature() -> None:
    pass
```
Now comes the authentication part, Solathon is a very powerful library with a lot of features which you can use to develop Solana applications in Python, however for authentication only one function from the library is required, let's import it:
```python
from solathon.utils import verify_signature
```
Now, we need to get our public key and signature from the API request headers, for that we would need to import `Request` object from `fastapi` and pass it as the first parameter:
```python
from fastapi import Request

@app.get("/verify_signature")
def verify_signature(request: Request) -> None:
    pass
```
Now, let's authenticate our request:
```python
@app.get("/verify_signature")
def verify_signature(request: Request) -> None:
    public_key = request.headers.get("public_key", None)
    # This can be passed in the "Authorization" header as well
    signature = request.headers.get("signature", None)
    try:
        verify_signature(public_key, signature)
    except:
        return {"error": "Unauthorized"}

    return {"message": public_key}
```
First we are getting our public key and signature from headers, the signature will be a 64 items long array of integers. Then we are running the `verify_signature` function which we imported earlier, the function returns nothing if the signature is valid, however if the signature is invalid, then it raises a `nacl.exceptions.BadSignatureError` exception, which we can catch using `try` and `except` block and return the error message in our API. Further more we can return a 401 HTTP status code as well.

That's it! I hope this post was helpful and I was able to teach Web3 authentication properly so that you can implement it in your next Solana backend in Python.