14

Câu hỏi này đã được hỏi một vài lần trên Stack, nhưng không có câu trả lời thực sự nào. Hãy để tôi cố gắng giải thích tình hình của tôi.Đăng nhập OAuth của Facebook Đăng nhập - access_token API trả lại "Mã ủy quyền này đã được sử dụng"

Chúng tôi sử dụng ứng dụng sử dụng thông tin đăng nhập Facebook OAuth2. Đăng nhập này được sử dụng để làm việc tốt cho đến tuần trước, và tất cả của một bất ngờ nó đang gây phiền hà cho chúng tôi bây giờ.

Application Lưu lượng:

Bước 1: ép tài khoản đăng nhập với nút Facebook trên trang web của chúng tôi

Bước 2: chuyển hướng đến trang Facebook đăng nhập/uỷ quyền

Bước 3 : Khi ủy quyền ứng dụng, cuộc gọi lại đến ứng dụng của chúng tôi, với tham số "mã" ngắn.

Bước 4: Thông số "mã" này sẽ được trao đổi cho mã thông báo truy cập 60 ngày sử dụng URL "https://graph.facebook.com/oauth/access_token".

Lỗi trong Bước 4:

Khi chúng tôi cố gắng để trao đổi cuộc sống ngắn "code" cho thẻ truy cập, chúng tôi nhận được lỗi này từ Facebook.

{"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100}} 

Observation:

  1. Đối với những người dùng đang mới đến đến các ứng dụng, các lỗi nói trên không xảy ra.
  2. Đối với người dùng cũ, cuộc gọi này không thành công với lỗi nêu trên.
  3. Đơn đăng ký của chúng tôi hiện đang hoạt động trong hơn 9 tháng và lỗi này chỉ xảy ra trong 7-10 ngày qua. Chúng tôi đã có hàng ngàn người dùng sử dụng thành công trước đó.

Những gì tôi đã nhận được từ Diễn đàn con:

Dưới đây là giải thích của tôi về những gì tôi đọc. Có thể không chính xác. Facebook có một số chính sách kỳ lạ đòi hỏi nhà phát triển ứng dụng phải duy trì mã 10 phút tạm thời cho đến khi mã 60 ngày thu được trong lần đăng nhập đầu tiên hết hạn. Vì vậy, chúng ta nên tạo một cookie với mã thông báo Access trên trình duyệt của người dùng. Tôi thậm chí còn có thể thấy mọi người sửa đổi mã của họ để tạo cookie.

Điều gì thực sự làm phiền tôi?

  1. Các giải pháp được đề xuất giả định rằng cookie mà chúng tạo ra sẽ luôn có trong trình duyệt của người dùng. Đây là một giả định tồi tệ để thực hiện, vì cookie có thể bị xóa bất cứ lúc nào.
  2. Tôi có một bí mật ứng dụng/ứng dụng khác mà tôi sử dụng để phát triển (ví dụ: localhost) và hoạt động hoàn hảo. Việc đăng nhập xảy ra tốt ở đó, nhưng chỉ có máy sản phẩm của nó có vấn đề.
  3. Vấn đề này đã không xảy ra trên máy sản xuất trong gần 10 tháng kể từ khi chúng tôi khởi chạy ứng dụng và nó đột nhiên xuất hiện. Tồi tệ nhất, tôi không thể nhận được bất kỳ hồ sơ nào về những thay đổi gần đây phá vỡ dòng chảy này.

Edit:

Hệ điều hành: Python, Google AppEngine. Chúng tôi không sử dụng bất kỳ SDK Facebook nào, chúng tôi thực hiện cuộc gọi HTTP trực tiếp đến tất cả các URL đăng nhập. Cuộc gọi không thành công: https://graph.facebook.com/oauth/access_token - chúng tôi đang chuyển appId, bí mật và mã (nhận được từ facebook) trong vòng 20 giây kể từ khi cuộc gọi đầu tiên diễn ra.

Hy vọng có đủ thông tin ở đây để cho thấy rằng mã của chúng tôi không hoàn toàn không chính xác. Bất kỳ lời khuyên/con trỏ từ những người đã gặp phải và giải quyết vấn đề này là Chào mừng. Nếu một lỗi Facebook của nó, và nhà phát triển Facebook đến để thông báo, tôi sẽ hạnh phúc hơn.

+0

Thông số mã chỉ có thể được trao đổi cho mã thông báo truy cập của người dùng một lần. Câu hỏi của bạn thiếu thông tin có thể sử dụng được về nền tảng/ngôn ngữ bạn đang sử dụng và cuộc gọi API chính xác của bạn là gì. – CBroe

+0

@CBroe - Cảm ơn bạn đã thông báo. Có - chúng tôi hiểu rằng thông số mã là một điều một lần và đó là lý do tại sao chúng tôi muốn trao đổi điều đó cho access_token, nhưng URL mã thông báo truy cập không thành công. Tôi đã bao gồm thông tin về nền tảng/ngôn ngữ. – Srivatsan

Trả lời

0

Tôi đã vật lộn với điều này trong một thời gian nữa. Bạn không chắc chắn nếu bạn đang sử dụng lớp Facebook PHP (từ những gì bạn viết, có vẻ như bạn không), tuy nhiên, nó có thể là một con trỏ anyways - vấn đề là thư viện Facebook PHP dường như có được mã thông báo từ mã tự động và tôi đã cố gắng làm điều đó một lần nữa.

+0

Tôi cũng gặp vấn đề này. Nó hoạt động tốt khi tôi gọi Bước 4 ở trên (graph.facebook.com/oauth/access_token) trước khi tôi sử dụng Facebook PHP SDK. Nhưng nếu tôi gọi nó sau, tôi nhận được "Mã ủy quyền này đã được sử dụng". Mã thông báo được lưu trữ trong SDK có định dạng khác với mã được trả về bởi điểm cuối và tôi không thấy ngày hết hạn trong SDK.Vì vậy, nếu các mã thông báo này khác nhau, tại sao Facebook trả về lỗi trong trường hợp này? –

4

Tôi đã giải quyết vấn đề này bằng cách sử dụng một GUID ngẫu nhiên được thêm vào mỗi url gọi lại mà tôi chuyển vào facebook. Có vẻ như mã mà facebook trả về được tạo thành từ một vài phần bao gồm tham số redirect_uri mà bạn phải chỉ định. Bằng cách sử dụng thủ thuật GUID này, ứng dụng của bạn tiếp tục hoạt động nhưng facebook cho rằng đó là một URL khác do đó tạo ra một mã mới.

Nếu bạn lưu trữ GUID đó trong một phiên tạm thời, nó luôn giống nhau. Đây là một phiên bản rất cắt giảm của những gì tôi có ý nghĩa. Tôi đang sử dụng C# nhưng giải pháp sẽ giống nhau:

Trước khi tôi bắt đầu quá trình oauth:

Session["facebook_buster"] = System.Guid.NewGuid().ToString(); 

Sau đó, để khởi động đăng nhập:

var facebook = new FacebookClient(); 

var loginUrl = facebook.GetLoginUrl(new 
{ 
    client_id = ..., 
    redirect_uri = ..."/facebook/oauthcallback?buster=" + Session["facebook_buster"].ToString(), 
    display = "popup", 
    scope = "publish_stream,user_photos" 
}); 

Và sau đó trong callback của tôi phương pháp, khi tôi muốn trao đổi mã đó cho một access_token mới:

var facebook = new FacebookClient(); 

dynamic result = facebook.Post("oauth/access_token", new 
{ 
    client_id = ..., 
    client_secret = ..., 
    redirect_uri = ..."/facebook/oauthcallback?buster=" + Session["facebook_buster"].ToString(), 
    code = Request["code"] // this is the returned code from the first method 
}); 

Lưu ý rằng phương pháp thứ hai tôi là người dùng ng cùng một khóa phiên để mã ủy quyền thành công.

Đã thử nghiệm tất cả các buổi sáng này bằng cách thu hồi quyền/thay đổi access_token được lưu trữ của tôi theo cách thủ công (trong db của tôi)/xóa hoàn toàn access_token đã lưu trữ của tôi và nó hoạt động mọi lúc.

Hy vọng điều này sẽ hữu ích!

+1

Không có xì gà, https://github.com/HabitRPG/habitrpg/issues/4221#issuecomment-61855507 – lefnire

+0

Cảm ơn bạn. Ngay từ cái nhìn đầu tiên, tôi không có cách nào để làm việc này. Nhưng tôi đã thực hiện nó trong PHP và thì đấy! Mã thông báo truy cập dài hạn một lần nữa. Đối với người mới tham gia sự cố này, Facebook phải sử dụng thông số 'redirect_uri' của bạn trong quá trình tạo mã dài hạn. Về cơ bản, chúng tôi đang lừa thuật toán của mình để tạo mã dài hạn độc đáo mà không mất 10 phút thời gian. Hoàn toàn thiên tài. –

+0

chỉ là một FYI, thêm một paramer bộ đệm ẩn để redirect_uri của tôi, khi nhận được url đăng nhập trong PHP, và nó có kết quả tương tự như thế này, tôi giả sử .. nó làm việc .. :) không thể tin rằng lỗi này với fb. kinda vô lý? nó đã nói rằng tôi đã sử dụng mã auth, nếu tôi giữ redirect_uri giống như một nỗ lực auth trước? thực sự bối rối, ồ. – jfaron

Các vấn đề liên quan