Ktor客户端 – CSRF POST请求

huangapple go评论61阅读模式
英文:

Ktor client - CSRF post request

问题

我正在进行一个项目,在该项目中,我使用Django作为服务器,使用Ktor客户端来创建Jetpack Compose应用程序以进行请求。然而,CSRF保护拒绝了我的登录请求(一个不安全的POST请求)。

由于Django内置了CSRF保护中间件,当我在本地主机上测试登录POST请求时,服务器会返回Forbidden (CSRF cookie not set.): /user/login/给客户端,登录功能无法正常工作。我尝试搜索一些文档和解决方案来禁用CSRF检查(@csrf_exempt),但它们对我不起作用。我已经在setting.py中添加了CSRF_TRUSTED_ORIGINS,如下所示(老实说,我不知道这些是否有效):

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:',
]

我还尝试禁用中间件,但没有效果。

有没有办法可以使用Ktor客户端满足Django的CSRF要求?或者如果不可能的话,我应该采取什么其他措施。

感谢任何答案。

英文:

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.

答案1

得分: 0

在Django的views.py中,我添加了如下的函数:

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

在Ktor客户端中,我添加了以下内容:

@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()
}

views.py中的get_csrf函数生成了一个随机的CSRF令牌。

Ktor客户端中的getCsrf()函数获取了生成的CSRF令牌。

然后,在您的登录(或任何需要CSRF的请求)中,添加了标头和Cookie,并设置了令牌的值。

这可能不是最佳解决方案,但它在Ktor中实现了CSRF验证(我认为)。

英文:

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

huangapple
  • 本文由 发表于 2023年1月9日 01:59:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75050146.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定