pythonfastapijinja2-cli

Endpoint(Router) Available for Authenticated user or not FastAPI


Today I have a question that I tried to solve myself, and looked around the internet with no success.

In a fastAPI website. While the user is not logged in, they can navigate to any page. But if logged in, and clicks on a link that does not have the auth signature current_user, it automatically logs out. Only open properly pages with current_user signature is what I expected since pages like: /me, `/update will contain the user logged-in data.

For a better understanding. I have a page "home" homepage, "users" that lists all users. These pages have to be available for authenticated users or not. But to work, I made an adaptation, and I'm sure it's not the best way to implement that.

Here is what I did. In my code, I made two methods, one for authenticated and one for unauthenticated, as the code below shows:

# router to index page not authenticated users
@app.get('/', include_in_schema=False)
def home(request: Request):
    return globals.templates.TemplateResponse('index.html', context= {'request': request})


# router to index page if users is authenticated (loged-in)
@app.get('/home', include_in_schema=False)
def home(request: Request, **cur_user: User= Depends(authentication.get_current_user)**):
    return globals.templates.TemplateResponse('index.html', context= {'request': request, 'user_in': cur_user})

As you can see, I created a path "/" for unauthenticated, and "/home" if logged in. But that is not functional at all because I would have to create 2 endpoints for all routers.

Plus, in my jinja2 I'll have to add an if..else for every link or page like this:

{% if not user_in %}
   <a class="navbar-brand" href="http://127.0.0.1:8000/">
      <img class="img-thumbnail" src="https://deliveryti.com/fastapi_images/domain.png">
   </a>
{% else %}
   <a class="navbar-brand" href="http://127.0.0.1:8000/home">
       <img class="img-thumbnail" src="https://deliveryti.com/fastapi_images/domain.png">
   </a>
{% endif %}

I'm not an expert in Fastap, but I could not find a way to manage session guys. I will be more than happy if someone can help me with this problem.

Thanks in advance.


Solution

  • The only changed I need was in the method 'get_current_user' I added an if...else that return 'None' if the user is not logged in.

    async def get_current_user(token: User=Depends(oauth2_scheme)):
        user = fake_decode_token(token)
        return user
    

    As you see this method only return user (in session) only works if user is logged in. That's why in the first question, I said that I created 2 routes for home and users, to test only but I knew that wasn't correct, also it was automatically login the user out when I click in a router that does not have this dependency.

    token: User=Depends(oauth2_scheme)
    

    Then, if click back to a route with dependency the user was in, so my project was having a very weird behavior that now is clear and make sense.

    So referring back to initial question the routers was:

    # router to index page not authenticated users
    @app.get('/', include_in_schema=False)
    def home(request: Request):
        return globals.templates.TemplateResponse('index.html', context= {'request': request})
    
    
    # router to index page if users is authenticated (loged-in)
    @app.get('/home', include_in_schema=False)
    def home(request: Request, **cur_user: User= Depends(authentication.get_current_user)**):
        return globals.templates.TemplateResponse('index.html', context= {'request': request, 'user_in': cur_user})
    

    Now I only have:

    @app.get('/', include_in_schema=False)
    def home(request: Request, cur_user: User= Depends(authentication.get_current_user)):
        return globals.templates.TemplateResponse('index.html', context= {'request': request, 'user_in': cur_user})
    

    I the jinja2 before:

    {% if not user_in %}
       <a class="navbar-brand" href="http://127.0.0.1:8000/">
          <img src="https://deliveryti.com/fastapi_images/domain.png">
       </a>
    {% else %}
       <a class="navbar-brand" href="http://127.0.0.1:8000/home">
           <img src="https://deliveryti.com/fastapi_images/domain.png">
       </a>
    {% endif %}
    

    Now:

    <a class="navbar-brand" href="http://127.0.0.1:8000/">
       <img src="https://deliveryti.com/fastapi_images/domain.png">
    </a>
    

    Hope this hep anyone with the same problem. I 'm sure there are other solutions but this one was simple and helped me to solve all the routers problems that I have.