Comments (9)
@sinisaos Thanks for sharing that example.
Here's some code from one of my apps which might also be helpful:
import datetime
from fastapi import FastAPI
from piccolo_api.csrf.middleware import CSRFMiddleware
from piccolo_api.openapi.endpoints import swagger_ui
from piccolo_api.session_auth.endpoints import session_login, session_logout
from piccolo_api.session_auth.middleware import SessionsAuthBackend
from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware
from starlette.routing import Route
app = FastAPI()
app.mount(
"/login/",
session_login(),
)
private_app = FastAPI(
routes=[
Route("/logout/", session_logout()),
],
middleware=[
Middleware(
AuthenticationMiddleware,
backend=SessionsAuthBackend(
increase_expiry=datetime.timedelta(minutes=30)
),
),
Middleware(CSRFMiddleware, allow_form_param=True),
],
docs_url=None,
redoc_url=None,
)
# The Swagger docs which come with FastAPI don't support CSRF middleware, so we mount
# a custom one which Piccolo provides (accessible at /private/docs):
private_app.mount("/docs/", swagger_ui(schema_url="/private/openapi.json"))
@private_app.get('/my-secret-endpoint/')
def my_endpoint():
# This is just a normal FastAPI endpoint, and is protected by Session Auth
pass
app.mount("/private/", private_app)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app)
You'll notice that there's basically two FastAPI apps - a root one, which contains anything which should be publicly accessible (such as the login endpoint) and a child app, which contains anything which should be protected by Session Auth.
from piccolo_api.
@wmshort This happens because session_logout()
uses the HTTP POST method and you access it using GET.
If you try curl curl -X POST --cookie "id=yourcookiesvalue" http://localhost:8000/logout/ (or your request.url)
you will see that you Successfully logged out
. It's easier for me not to use session_logout()
but a logout endpoint that I can access from /docs
like in my previous example.
# your imports
from starlette.responses import JSONResponse
app = FastAPI(docs_url=None)
app.mount("/docs/", swagger_ui(schema_url="../openapi.json"))
@app.post("/logout/", tags=["Logout"])
async def logout(request: Request):
response = JSONResponse(
{
"message": "You are logged out",
},
status_code=200,
)
response.delete_cookie("id") # or response.delete_cookie("yourcookie")
return response
from piccolo_api.
If you've got a HTML template, you can put something like this in to logout:
<form action="/private/logout/" method="POST">
<!--
You need to get the CSRF token. The CSRF middleware adds it to the FastAPI / Starlette request,
so if you add the request to the Jinja context, you can access the CSRF token from the template.
Alternatively you can get the csrftoken from the cookie using jQuery or something.
-->
<input name="csrftoken" type="hidden" value="{{ request.scope.get('csrftoken') }}" />
<button>Logout</button>
</form>
An example of adding the request to the Jinja context:
async def my_endpoint(self, request: Request):
template = ENVIRONMENT.get_template("app.html.jinja")
content = template.render(request=request)
return HTMLResponse(content)
from piccolo_api.
@wmshort Piccolo Admin use SessionAuth. You can also try something like this.
auth_middleware = partial(
AuthenticationMiddleware,
backend=SessionsAuthBackend(
auth_table=BaseUser,
session_table=SessionsBase,
admin_only=False,
),
)
app = FastAPI(docs_url=None)
app.mount("/docs/", swagger_ui(schema_url="../openapi.json"))
# login endpoint which which provide login form
app.mount(
path="/login/",
app=session_login(
auth_table=BaseUser,
session_table=SessionsBase,
redirect_to="/docs/",
),
)
@app.post("/logout/", tags=["Logout"])
async def logout(request: Request):
response = JSONResponse(
{
"message": "You are logged out",
},
status_code=200,
)
response.delete_cookie("id")
return response
I hope this helps.
from piccolo_api.
Cool, thanks, I will tinker around with this! Maybe I am being daft, but how, in this example, do you hook up the auth_middleware
to app
? And are these endpoints the equivalent of what's available from piccolo_api.session_auth.endpoints
?
Thanks again for your suggestions!
from piccolo_api.
@wmshort Yes. You need endpoints from piccolo_api.session_auth.endpoints
.
from piccolo_api.
Thanks, both, this really helped! The key was thinking about them as distinct apps and separating out the different endpoints. The only sticky thing remaining is that the session_logout
endpoint is giving me a "method not allowed" error, but everything else is running smoothly now.
from piccolo_api.
Yeah, it only supports POST. I had a look at the docs, and this isn't mentioned, so needs adding.
from piccolo_api.
Closing issue, as the last remaining question appears to be addressed by #82
from piccolo_api.
Related Issues (20)
- TypeError: __init__() got an unexpected keyword argument 'excluded_paths' HOT 5
- Feature to modify body and query_parameters in `PiccoloCRUD` HOT 8
- Fix code scanning alert - Unused global variable
- Batch version of the get endpoint HOT 6
- Drop Python 3.7 support
- Catch foreign key constraint errors in `PiccoloCRUD`
- `schema_extra` param not passed to `pydantic_model_{output | optional | plural}` methods HOT 1
- Piccolo Admin API docs are not rendering
- Better error display on PATCH request
- Alpha version for Pydantic 2.0 / Piccolo 1.0a1? HOT 2
- PiccoloCRUD `post_single` return id of the inserted row instead of the row HOT 3
- Add `ne` operator
- Python 3.12 support
- RateLimitingMiddleware tests failed HOT 5
- Stop multi-dimensional arrays from breaking
- Issue with updating and bulk updating `BaseUser` via admin panel HOT 15
- Updating middleware syntax HOT 6
- Make `default-src` configurable in `CSPMiddleware`
- Hide parameter in Validators to hide Piccolo Admin table link from sidebar if the validators fail. HOT 8
- Add `excluded_paths` to `SessionsAuthBackend`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from piccolo_api.