OAuth Login

Mutation · loginWithOAuth

loginWithOAuth(input: OAuthLoginInput!): AuthPayload!

Sau khi provider chuyển hướng trình duyệt về trang /login với code và state, client kiểm tra state đã lưu, rồi gọi mutation này bằng mã ủy quyền và PKCE verifier tương ứng. API đổi mã với provider, đọc hồ sơ và đăng nhập tài khoản đã biết hoặc tạo/liên kết tài khoản theo email được provider xác minh. Mutation tạo phiên mới với access token và refresh token.

Gửi qua HTTP POST /graphql. Không cần access token hoặc quyền thành viên workspace/conversation. API không nhận state ở mutation này; client phải kiểm tra nó trước khi gọi. Các mutation xác thực dùng chung giới hạn 20 lần/phút theo IP trên mỗi tiến trình API; vượt giới hạn trả RATE_LIMITED.

Input

Đối sốKiểu GraphQLBắt buộcÝ nghĩa
inputOAuthLoginInput!CóDữ liệu trả về từ provider và PKCE verifier; schema không khai báo mặc định.

OAuthLoginInput

TrườngKiểu GraphQLBắt buộcQuy tắc
providerOAuthProviderName!CóGOOGLE; phải là provider dùng khi tạo URL cấp quyền.
codeString!CóMã ủy quyền trong URL provider chuyển hướng về, tối đa 2048 ký tự. Không có kiểm tra độ dài tối thiểu riêng; mã rỗng sẽ không đổi được với provider.
codeVerifierString!CóTừ 43 đến 128 ký tự thuộc A–Z, a–z, 0–9, -, ., _, ~. Phải là verifier đã dùng để tạo codeChallenge khi bắt đầu luồng.

Mọi trường đều là !: không thể bỏ qua hoặc gửi null. API dùng redirect_uri cố định từ cấu hình khi đổi mã; client không truyền URI tùy ý.

Output

Trả về AuthPayload!: một đối tượng không null khi đăng nhập thành công. OAuth tạo refresh token phiên dài hạn theo JWT_REFRESH_TTL (mặc định 30 ngày); access token theo JWT_ACCESS_TTL (mặc định 15 phút).

AuthPayload

TrườngKiểu GraphQLÝ nghĩa
accessTokenString!JWT mới dùng để xác thực yêu cầu API.
refreshTokenString!Token của phiên mới, dùng với refreshToken.
userUserProfile!Hồ sơ tài khoản đã được đăng nhập; xem UserProfile.

UserProfile

TrườngKiểu GraphQLÝ nghĩa
idID!ID người dùng.
usernameString!Tên người dùng; với tài khoản mới, API tạo từ tên định danh của provider và thêm hậu tố nếu trùng.
displayNameString!Tên hiển thị của tài khoản.
emailString!Email của tài khoản.
avatarUrlStringURL ảnh đại diện hoặc null.

Với danh tính provider đã biết, API đăng nhập tài khoản liên kết. Lần đầu đăng nhập cần email được Google xác minh qua email_verified. Nếu email trùng tài khoản đã xác minh, API gắn danh tính provider vào tài khoản đó. Nếu email chỉ thuộc đăng ký mật khẩu chưa xác minh, API thay tài khoản chưa xác minh bằng tài khoản provider mới; mật khẩu cũ không được giữ. Nếu tài khoản cùng email đã gắn một danh tính khác của chính provider đó, API trả OAUTH_ACCOUNT_EXISTS.

Ví dụ

mutation OAuthLogin($input: OAuthLoginInput!) {
  loginWithOAuth(input: $input) {
    accessToken
    refreshToken
    user { id username displayName email avatarUrl }
  }
}

Biến minh họa sau khi client đã kiểm tra state:

{
  "input": {
    "provider": "GOOGLE",
    "code": "example-authorization-code",
    "codeVerifier": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  }
}

Phản hồi minh họa:

{
  "data": {
    "loginWithOAuth": {
      "accessToken": "example.access.token",
      "refreshToken": "example-refresh-token",
      "user": {
        "id": "user_123",
        "username": "lan_nguyen",
        "displayName": "Lan Nguyễn",
        "email": "[email protected]",
        "avatarUrl": null
      }
    }
  }
}

Provider chưa cấu hình trả OAUTH_NOT_CONFIGURED. Mã sai, hết hạn hoặc lỗi khi gọi provider trả OAUTH_FAILED. Lần đăng nhập đầu không có email được provider xác minh trả OAUTH_EMAIL_UNVERIFIED. Input sai quy tắc trả BAD_USER_INPUT.

Chữ ký operation được tạo từ GraphQL schema.