# FastAPI SeaSurf

***

**1. Define a CSRF Protection Middleware**

```python
from fastapi_seasurf import SeaSurfMiddleware

app.add_middleware(
    SeaSurfMiddleware,
    secret_key="YOUR_SECRET_KEY",
    csrf_cookie_name="csrftoken"
)
```

**2. Generate CSRF Token**

```python
@app.get("/csrf-token")
async def get_csrf_token():
    token = await SeaSurfMiddleware.get_csrf_token()
    return {"csrf_token": token}
```

**3. Inject CSRF Token into HTML**

```html
<form action="/submit" method="post">
  <input type="hidden" name="csrf_token" value="{{ csrf_token }}">
  <input type="text" name="username">
  <input type="submit" value="Submit">
</form>
```

**4. Validate CSRF Token**

```python
@app.post("/submit")
async def submit_form(username: str = Form(...)):
    token = request.headers.get("X-CSRF-Token")
    if not await SeaSurfMiddleware.validate_csrf_token(token):
        # CSRF token validation failed
        raise HTTPException(status_code=403)
```

**5. Customize CSRF Cookie Name**

```python
app.add_middleware(
    SeaSurfMiddleware,
    secret_key="YOUR_SECRET_KEY",
    csrf_cookie_name="my_csrf_token"
)
```

**6. Disable CSRF Protection**

```python
app.add_middleware(
    SeaSurfMiddleware,
    secret_key=None,
    csrf_cookie_name="csrftoken"
)
```

**7. Define Multiple CSRF Protection Middlewares**

```python
app.add_middleware(
    SeaSurfMiddleware,
    secret_key="SECRET_KEY_1",
    csrf_cookie_name="csrftoken_1"
)

app.add_middleware(
    SeaSurfMiddleware,
    secret_key="SECRET_KEY_2",
    csrf_cookie_name="csrftoken_2"
)
```

**8. Generate CSRF Token for AJAX Requests**

```python
@app.post("/ajax-csrf-token")
async def get_ajax_csrf_token():
    token = await SeaSurfMiddleware.get_csrf_token(request)
    return {"csrf_token": token}
```

**9. Set CSRF Token Cookie Expires Time**

```python
app.add_middleware(
    SeaSurfMiddleware,
    secret_key="YOUR_SECRET_KEY",
    csrf_cookie_max_age=600  # 10 minutes
)
```

**10. Use SeaSurfMiddleware in an ASGI Application**

```python
import fastapi.middleware.asgi

app = fastapi.FastAPI()

middleware = [
    fastapi.middleware.asgi.CORSMiddleware(
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    ),
    SeaSurfMiddleware(
        secret_key="YOUR_SECRET_KEY",
        csrf_cookie_name="csrftoken"
    )
]

asgi_app = fastapi.middleware.asgi.ASGIMiddleware(app, middleware)
```

**11. Set CSRF Token Cookie SameSite Attribute**

```python
app.add_middleware(
    SeaSurfMiddleware,
    secret_key="YOUR_SECRET_KEY",
    csrf_cookie_samesite="Lax"
)
```

**12. Generate CSRF Token for Single-Page Applications (SPAs)**

```python
@app.get("/spa-csrf-token/{spa_name}")
async def get_spa_csrf_token(spa_name: str):
    token = await SeaSurfMiddleware.create_spa_csrf_token(
        request, spa_name
    )
    return {"csrf_token": token}
```

**13. Store CSRF Token in a Database**

```python
from fastapi.responses import HTMLResponse

@app.get("/set-csrf-token")
async def set_csrf_token(response: HTMLResponse):
    token = await SeaSurfMiddleware.get_csrf_token()
    response.set_cookie("csrftoken", token, httponly=True)
    return response
```

**14. Use a Cache for CSRF Tokens**

```python
from fastapi.security import HTTPBearer
from fastapi.security.csrf import CSRFAuthorization

csrf_cache = {}

class CSRFTokenBearer(HTTPBearer):
    def __init__(self, auto_error: bool = True):
        super().__init__(auto_error=auto_error)

    async def __call__(self, request: Request) -> CSRFAuthorization:
        token = await super().__call__(request)
        if token.csrf_token not in csrf_cache:
            raise HTTPException(status_code=403)
        return token
```

**15. Customize CSRF Error Handler**

```python
from fastapi_seasurf import SeaSurfMiddleware, SeaSurfTokens
from fastapi.responses import HTMLResponse

@app.exception_handler(SeaSurfTokens.ValidationError)
async def csrf_error_handler(request: Request, exc: SeaSurfTokens.ValidationError):
    return HTMLResponse("CSRF token validation failed.")
```

**16. Use Single-Use CSRF Tokens**

```python
app.add_middleware(
    SeaSurfMiddleware,
    secret_key="YOUR_SECRET_KEY",
    csrf_token_max_age=1  # Single-use token
)
```

**17. Set CSRF Token Cookie Path**

```python
app.add_middleware(
    SeaSurfMiddleware,
    secret_key="YOUR_SECRET_KEY",
    csrf_cookie_path="/"
)
```

**18. Use SeaSurfMiddleware with Nginx**

```nginx
location / {
  proxy_pass http://localhost:8000;
  proxy_set_header X-CSRF-Token $http_csrftoken;
}
```

**19. Use SeaSurfMiddleware with gunicorn**

```gunicorn
gunicorn app:app --bind 0.0.0.0:8000 --forwarded-allow-ips='*'
```

**20. Set CSRF Token Cookie Secure Attribute**

```python
app.add_middleware(
    SeaSurfMiddleware,
    secret_key="YOUR_SECRET_KEY",
    csrf_cookie_secure=True
)
```

**21. Use SeaSurfMiddleware with Hypercorn**

```
hypercorn app:app --bind 0.0.0.0:8000 --forwarded-allow-ips '*'
```

**22. Use SeaSurfMiddleware with UVicorn**

```
uvicorn app:app --host 0.0.0.0 --port 8000 --forwarded-allow-ips '*'
```

**23. Use SeaSurfMiddleware with Daphne**

```
daphne app.asgi:app --bind 0.0.0.0:8000 --forwarded-allow-ips '*'
```

**24. Use SeaSurfMiddleware with Waitress**

```
waitress-serve --port=8000 app:app
```

**25. Use SeaSurfMiddleware with Bjoern**

```
bjoern --bind 0.0.0.0:8000 app:app
```

**26. Use SeaSurfMiddleware with Gevent**

```
gevent-websocket -p 8000 app:app
```

**27. Use SeaSurfMiddleware with Twisted**

```
twistd web --server port=8000 wsgi.Resource:app
```

**28. Use SeaSurfMiddleware with Tornado**

```
tornado.web.Application([
    (r"/", app)
]).listen(8000)
```

**29. Use SeaSurfMiddleware with Zappa**

```yaml
functions:
  app:
    handler: app.app
```

**30. Use SeaSurfMiddleware with Zeit Now**

```yaml
version: 2
runtime: nodejs16
```

**31. Use SeaSurfMiddleware with Heroku**

```yaml
web: gunicorn app:app
```

**32. Use SeaSurfMiddleware with AWS Lambda**

```py
import uvicorn

def lambda_handler(event, context):
    return uvicorn.run(app, host="0.0.0.0", port=8000)
```

**33. Use SeaSurfMiddleware with Azure Functions**

```py
import fastapi

app = fastapi.FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello, world!"}
```

**34. Use SeaSurfMiddleware with Google Cloud Functions**

```py
import functions_framework

@functions_framework.http
def app(request):
    request.get_data()
    return 'OK', 200
```

**35. Use SeaSurfMiddleware with IBM Cloud Functions**

```py
import os

from functions_framework import http

@http.route("/")
def app(request):
    request.get_data()
    return 'OK', 200
```

**36. Use SeaSurfMiddleware with Oracle Cloud Functions**

```py
import os

from functions_framework import http

@http.route("/")
def app(event, context):
    event.data
    return 'OK', 200
```
