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.
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.