Tôi nên sử dụng phương pháp nào cho yêu cầu đăng nhập (xác thực)?


93

Tôi muốn biết tôi nên sử dụng phương thức http nào khi thực hiện yêu cầu đăng nhập và tại sao? Vì yêu cầu này tạo ra một đối tượng (một phiên người dùng) trên máy chủ, tôi nghĩ nó phải là POST, bạn nghĩ sao? Nhưng vì yêu cầu đăng nhập phải là idmpotent, nên nó có thể là PUT, phải không?

Cùng một câu hỏi cho yêu cầu đăng xuất, tôi có nên sử dụng phương thức DELETE không?

Câu trả lời:


77

Nếu yêu cầu đăng nhập của bạn là thông qua người dùng cung cấp tên người dùng và mật khẩu thì tốt hơn là POST, vì chi tiết sẽ được gửi trong nội dung thông báo HTTP chứ không phải URL. Mặc dù nó vẫn sẽ được gửi văn bản thuần túy, trừ khi bạn đang mã hóa qua https.

Phương thức HTTP DELETE là một yêu cầu xóa nội dung nào đó trên máy chủ. Tôi không nghĩ rằng việc XÓA một phiên người dùng trong bộ nhớ thực sự là như ý định; hơn nữa nó để xóa bản ghi người dùng. Vì vậy, khả năng đăng xuất có thể chỉ là GET, ví dụ như www.yoursite.com/logout.


1
Về yêu cầu đăng nhập, tôi đã thêm điều gì đó vào câu hỏi của mình nói rằng nó có thể là PUT, tôi không do dự với GET. +1 cho câu trả lời chi tiết
greg0ire

1
ok - Tôi nghĩ PUT thực sự đang tạo ra một thứ gì đó trên máy chủ. Vì vậy, theo nghĩa RESTful, tôi đoán đó là những gì bạn CÓ THỂ sử dụng nếu tạo một người dùng mới. Và người dùng sẽ được tạo tại URL bạn chỉ định. Tuy nhiên, đối với những thứ thực sự thoáng qua như phiên http, thì tôi sẽ đăng nhập qua POST.
Planetjones

Tôi nghĩ rằng thực tế là phiên http là thoáng qua có ý nghĩa của bạn. Tôi sẽ làm như bạn đã nói, cảm ơn.
greg0ire

16
Tôi không đồng ý rằng LOGOUT phải là GET vì chỉ cần gửi email người dùng có thẻ hình ảnh có thuộc tính src là "www.yoursite.com/logout" sẽ đăng xuất người dùng đó.
Vytautas Butkus

2
GET không có nhiều ý nghĩa. Một đầu vào khác về vấn đề này có thể được tìm thấy tại đây: stackoverflow.com/questions/3521290/logout-get-or-post
thasmo

37

Tôi tin rằng bạn có thể dịch các phương thức LOGIN & LOGOUT thành các hoạt động CRUD cơ bản TẠO & XÓA. Vì bạn đang tạo một tài nguyên mới có tên là SESSION và phá hủy nó khi đăng xuất:

  1. ĐĂNG / đăng nhập - tạo phiên
  2. DELETE / đăng xuất - hủy phiên

Tôi sẽ không bao giờ thực hiện LOGOUT là GET chỉ vì bất kỳ ai cũng có thể thực hiện một cuộc tấn công chỉ đơn giản bằng cách gửi email có thẻ IMG hoặc liên kết đến trang web có thẻ IMG như vậy. ( <img src="youtsite.com/logout" />)

PS Đã lâu, tôi đã tự hỏi làm thế nào bạn sẽ tạo một đăng nhập / đăng xuất RESTful và hóa ra nó thực sự đơn giản, bạn làm điều đó giống như tôi đã mô tả: sử dụng / session / endpoint với các phương thức CREATE và DELETE và bạn ổn. Bạn cũng có thể sử dụng UPDATE nếu bạn muốn cập nhật phiên theo cách này hay cách khác ...


4
Việc thực hiện yêu cầu XÓA gần như dễ dàng như yêu cầu GET với các công cụ trình duyệt hiện đại, một số công cụ có sẵn ngay trong trình duyệt, giống như đưa ra yêu cầu XHR trực tiếp từ bảng điều khiển của trình duyệt. Vẫn ủng hộ vì bạn đã nói về ngữ nghĩa, điều này cũng quan trọng, cũng như cơ sở dữ liệu.
chạy thận

6

Đây là giải pháp của tôi dựa trên các hướng dẫn và khuyến nghị REST:

ĐĂNG NHẬP - tạo tài nguyên

Yêu cầu:

POST => https://example.com/sessions/

BODY => {'login': 'login@example.com', 'password': '123456'}

Phản ứng:

http status code 201 (Created)

{'token': '761b69db-ace4-49cd-84cb-4550be231e8f'}

LOGOUT - xóa tài nguyên

Yêu cầu:

DELETE => https://example.com/sessions/761b69db-ace4-49cd-84cb-4550be231e8f/

Phản ứng:

http status code 204 (No Content)

2

Về phương pháp đăng xuất:

Trong tài liệu Spring (Java Framework), họ nêu rõ rằng yêu cầu POST được ưu tiên hơn, vì GET khiến bạn dễ bị CSRF (Cross-Site Request Forgery) và người dùng có thể bị đăng xuất.

Thêm CSRF sẽ cập nhật LogoutFilter để chỉ sử dụng HTTP POST. Điều này đảm bảo rằng đăng xuất yêu cầu mã thông báo CSRF và người dùng độc hại không thể buộc đăng xuất người dùng của bạn.

Xem: https://docs.spring.io/spring-security/site/docs/current/reference/html/web-app-security.html#csrf-logout

Đăng nhập cũng nên sử dụng POST (nội dung có thể được mã hóa, xem các câu trả lời khác).


0

Đối với yêu cầu đăng nhập, chúng ta nên sử dụng phương thức POST. Bởi vì dữ liệu đăng nhập của chúng tôi được bảo mật và cần bảo mật. Khi sử dụng phương pháp POST, dữ liệu được gửi đến máy chủ trong một gói. Nhưng trong phương thức GET, dữ liệu được gửi đến máy chủ theo sau là url như nối thêm với yêu cầu url mà mọi người sẽ thấy.

Vì vậy, để xác thực an toàn và quá trình ủy quyền, chúng ta nên sử dụng phương pháp POST.

Tôi hy vọng giải pháp này sẽ giúp bạn.

Cảm ơn


0

Để đăng nhập, tôi sử dụng POST, dưới đây là mã của tôi cho phương thức ĐĂNG NHẬP, tôi đã sử dụng Nodejs với Express và Mongoose

your router.js
     const express = require("express");
     const router = express.Router();

     router.post("/login", login);

your controller.js
     export.login = async(req, res) => {
         //find the user based on email
         const {email, password} = req.body; 

           try{
                const user =  awaitUser.findOne({email});
                if(user==null) 
                 return res.status(400).json({err : "User with 
                         email doesnot exists.Please signup"});
          }
           catch(error){
                 return res.status(500).json({err : 
                                     error.message});
               }

         //IF EVERYTHING GOES FINE, ASSIGN YOUR TOKEN
          make sure you have JWT installed 
         const token = jwt.sign({_id: user._id}, YOUR_SECRET_KEY);

         res.cookie('t');

         const {_id, name, email} = user;
         return res.json({token, user : {_id, email, name}});



     }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.