Search code examples
djangokotlincsrfktordjango-csrf

Ktor client - CSRF post request


I am doing a project where I am using django for server and ktor client for jetpack compose application to make request.However the CSRF protection reject my login request(An unsafe post request).

As django has a built-in CSRF protection middleware, when I am testing the login post request with localhost, the server return Forbidden (CSRF cookie not set.): /user/login/ to the client and the login function cannot work. I tried to search for some documents and solutions to disable CSRF check (@csrf_exempt) but they are not working for me.I have added the CSRF_TRUSTED_ORIGINS in setting.py as the following(To be honest I don't know if these works or not):

CSRF_TRUSTED_ORIGINS = [
    'http://localhost',
    'http://*.127.0.0.1:*',
    'http://10.0.2.2',
    'http://127.0.0.1',
    'https://127.0.0.1',
    'https://127.0.0.1:*',
    'https://127.0.0.1:',
]

I have also tried to disable the middleware but not work.

Is there any way that I can use ktor client to satisfy the CSRF thing from django?? Or what else should I do if that is not possible.

Thank you for any answer.


Solution

  • In django views.py I add a function like this:

    @csrf_exempt
    def get_csrf(request):
        token = csrf.get_token(request)
        response = JsonResponse({'detail': 'CSRF cookie set','CSRFToken': token})
        return response
    

    In the ktor client , I add something like this:

    @Serializable
    data class Csrf_response(
        val detail:String,
        val CSRFToken : String,
    )
    
    private suspend fun getCsrf():Csrf_response{
            return httpClient.post("${hostUrl}/user/get_csrf/").body()
        }
    
        
        suspend fun postLogin(loginCredential: LoginCredential): UserInfo {
            val token =  getCsrf()
    //        Log.d("token: ",token.CSRFToken)
            return httpClient.post("${hostUrl}/user/login/") {
                setBody(loginCredential)
                cookie(name = "X-CSRFToken", value = token.CSRFToken)
                header("X-CSRFToken",token.CSRFToken)
            }.body()
        }
    

    The function get_csrf in views.py generate a random csrf token.

    The getCsrf() function in ktor client get the generated csrf token.

    Then in your login(or whatever request needs csrf) add the header and cookie and set the value of the token.

    This might not be the best solution but it implements the csrf validation in ktor(I think).