2017-06-07 48 views
0

我登錄我的應用程序。但是,我需要在應用程序中登錄CRSF令牌。首先,我嘗試發送一個cookie並獲得一個csrf。但我是初學者,它不起作用。其實,我不知道我做了什麼。如何使用(Django)CSRF登錄Android應用程序?

我使用這個應用程序跨我的網站。我使用Django的網站和API(Django Rest Framework)爲Android應用程序。

private static final String KEY_LOGIN = "http://192.168.1.102:8080/api-auth/login/"; 
private static final String KEY_CSRF = "csrf"; 
public static final String KEY_EMAIL = "email"; 
public static final String KEY_PASSWORD = "password"; 

CookieManager cookieManager; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_home); 


    editTextEmail = (EditText) findViewById(R.id.editTextEmail); 
    editTextPassword = (EditText) findViewById(R.id.editTextPassword); 

} 

private void loginUser() 
{ 
    final HttpCookie cookie = new HttpCookie("lang", "tr"); 
    try { 
     cookieManager.getCookieStore().add(new URI("http://192.168.1.102:8080/api-auth/login/"), cookie); 
    } catch (URISyntaxException e) { 
     e.printStackTrace(); 
    } 

    final String email = editTextEmail.getText().toString().trim(); 
    final String password = editTextPassword.getText().toString().trim(); 

    StringRequest stringRequest = new StringRequest(Request.Method.POST,KEY_LOGIN,new Response.Listener<String>() 
    { 

     @Override 
     public void onResponse(String response) { 
      if(response.contains("is_admin")) { 
      openProfileCompany();} 

     else 
     { 
      openProfileUser(); 
     }}}, 

    new Response.ErrorListener() 
    { 
     @Override 
     public void onErrorResponse(VolleyError error) 
     { 
      Toast.makeText(Home.this,error.toString(),Toast.LENGTH_LONG).show(); 
     } 
    }){ 

     public String csrf; 

     @Override 
protected Map<String,String> getParams(){ 

    Map<String,String> params = new HashMap<String,String>(); 
    params.put(KEY_EMAIL,email); 
    params.put(KEY_PASSWORD,password); 
    params.put(KEY_CSRF,csrf); 

    return params; 
} 
    }; 
+0

對於android客戶端,我建議使用django-rest-framework令牌認證,如果你願意,我可以給你django代碼和okhttp代碼。 – Ykh

+0

謝謝你的有趣。如果你能把它們給我,那對我來說很好。 – AlpYuktug

回答

0

Django和Django的REST框架: setting.py

REST_FRAMEWORK = { 
    'DEFAULT_PERMISSION_CLASSES': (
     'rest_framework.permissions.IsAuthenticatedOrReadOnly', 
    ), 
    'DEFAULT_AUTHENTICATION_CLASSES': (
     'user.auth.TokenAuthentication', 
    ), 
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler', 
    'PAGE_SIZE': 5, 
    'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S', 
} 

用戶> auth.py

class TokenAuthentication(TokenAuthentication): 
    # Authorization:Token 401f7ac837da42b97f613d789819ff93537bee6a 
    keyword = 'Token' 
    model = Token 

    def authenticate_credentials(self, key): 
     model = self.get_model() 
     try: 
      token = model.objects.select_related('user').get(access_token=key) 
     except model.DoesNotExist: 
      raise exceptions.AuthenticationFailed(_('Invalid token.')) 

     if not token.user.is_active: 
      raise exceptions.AuthenticationFailed(_('User inactive or deleted.')) 

     return token.user, token 

令牌模型:

def generate_key(): 
    return binascii.hexlify(os.urandom(20)).decode() 
class Token(models.Model): 
    user = models.OneToOneField(settings.AUTH_USER_MODEL, 
           null=True, 
           on_delete=models.CASCADE, 
           verbose_name=u'user') 
    access_token = models.CharField(unique=True, 
            default='', 
            max_length=40, 
            verbose_name=u'Token') 
    refresh_token = models.CharField(unique=True, 
            default='', 
            max_length=40, 
            verbose_name=u'Token') 

    class Meta: 
     verbose_name = 'Token' 
     verbose_name_plural = 'Token' 

    def save(self, *args, **kwargs): 
     if not self.access_token: 
      self.access_token = generate_key() 
     if not self.refresh_token: 
      self.refresh_token = generate_key() 
     return super(Token, self).save(*args, **kwargs) 

    def refresh_access_token(self): 
     self.access_token = generate_key() 

    def __str__(self): 
     return self.access_token 

創建令牌實例當你android客戶端註冊像Token.objects.create(user=user),當用戶登錄,返回令牌Android客戶端,是這樣的:

try: 
    token = user.token 
except ObjectDoesNotExist: 
    token = Token.objects.create(user=instance) 
data = {'id': user.id, 'token': token.access_token)} 
return Response(data) 

您的Android客戶端獲取自己的令牌,該令牌將是您的客戶端ID,將其保存在Preferences.Then添加頁眉到您的android HttpClient,關鍵是Authorization,值爲Token xxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxx是由django返回的令牌字符串,那麼您的android發送的每個請求都將通過令牌授權,您可以通過request.user獲得您的用戶在django。所有,如果你有另一個問題,請隨時問我。