ログイン認証
認証方式について
SaaS を含む Web アプリケーションでは、代表的な認証方式として以下の 2 つがあります。
・セッションベース認証
・トークンベース認証
SaaSus Platform では、トークンベース認証 を採用しています。
以下 に、それぞれの認証方式について説明します。
認証の種類
セッションベース認証
セッションベース認証は、サーバ側で生成したセッションIDを使用してクライアントが認証を行う方式 です。
この方式の特徴として、ステートフルな通信が可能 である一方、トークンベース認証と比較してサーバの負荷が高くなる 点が挙げられます。

トークンベース認証
トークンベース認証は、トークンの情報を利用してクライアントが認証を行う方式 です。
この方式の特徴として、サーバ側で認証情報を保持する必要がないため、セッションベース認証と比較してサーバの負荷が低く、ステートレスな通信が可能である 点が挙げられます。

セッションベース認証とトークンベース認証の違い
セッションベース認証は、サーバ側で認証のための情報を保持する のに対し、トークンベース認証は サーバ側に認証情報を保持せず、トークンの検証のみで認証を行う という違いがあります。
また、トークンベース認証は、ユーザー数が増加した際のサーバ負荷がセッションベース認証よりも低く、よりスケーラブルなシステムを実現できる というメリットがあります。
SaaSus Platform における認証
SaaSus Platform では トークンベース認証 を採用しています。
トークンの生成および検証は、SaaSus SDK を利用し、SaaSus Platform の API を呼び出すことで実施します。

認証タイミングについて
ログインが必要な処理を実行する場合、サーバがリクエストを受けたタイミングで認証を行う必要があります。
SaaSus Platform では、SaaSus SDK を利用し、リクエストごとに認証を実施します。
SDK の ユーザー情報取得処理 を実行することで、以下の情報を取得できます。
・トークンの検証
・ログインユーザの情報取得(ユーザ情報、テナント情報、権限)
ログインが必要な処理が複数ある場合、各処理の先 頭で SaaSus SDK を利用し、ユーザー情報を取得することで、ログイン状態を確認する必要があります。

処理数が増えると、個別に認証処理を実装することが困難になるため、フレームワークのミドルウェア機能を活用し、一律で認証をチェックする仕組みを導入することを推奨します。

トークンの種類
SaaSus Platform では、以下の3種類のトークンを生成します。
・IDトークン
・アクセストークン
・リフレッシュトークン
IDトークン
IDトークンは認証のために使用するトークンであり、有効期限は1時間です。
有効期限を過ぎるとトークンは無効となり、SaaS 利用者はログアウト状態となります。
- PHP
- Node.js
- Go
- Python
- Java
- C#(.Net8)
- C#(.Netfw4.8)
// Laravelの場合、ルーティングファイルで SaaSus SDK 標準の Auth Middleware を利用する
// ルーティングは、SaaSus Platformで認証が必要な機能を記載する
Route::middleware(\AntiPatternInc\Saasus\Laravel\Middleware\Auth::class)->group(function () {
Route::get('/userinfo', [IndexController::class, 'userinfo']);
Route::get('/users', [IndexController::class, 'users']);
Route::get('/tenant_attributes', [IndexController::class, 'tenantAttributes']);
Route::get('/user_attributes', [IndexController::class, 'userAttributes']);
Route::post('/user_register', [IndexController::class, 'userRegister']);
Route::delete('/user_delete', [IndexController::class, 'userDelete']);
Route::get('/delete_user_log', [IndexController::class, 'deleteUserLog']);
Route::get('/pricing_plan', [IndexController::class, 'pricingPlan']);
Route::get('/tenant_attributes_list', [IndexController::class, 'tenantAttributesList']);
Route::post('/self_sign_up', [IndexController::class, 'selfSignUp']);
Route::post('/logout', [IndexController::class, 'logout']);
});
// Expressの場合、SaaSus SDK 標準の AuthMiddleware を利用する
// ルーティングは、SaaSus Platformで認証が必要な機能を記載する
import { AuthMiddleware } from 'saasus-sdk'
app.use([
'/userinfo',
'/users',
'/tenant_attributes',
'/user_register',
'/user_delete',
'/delete_user_log',
'/pricing_plan',
'/tenant_attributes_list',
'/self_sign_up'
], AuthMiddleware)
// 作成したauthMiddlewareEchoを使用することでユーザー認証を実施、UserInfo がコンテキストに設定される
authMiddleware := authMiddlewareEcho(idTokenGetter)
e.GET("/userinfo", getMe, authMiddleware)
e.GET("/users", getUsers, authMiddleware)
e.GET("/tenant_attributes", getTenantAttributes, authMiddleware)
e.GET("/user_attributes", getUserAttributes, authMiddleware)
e.GET("/pricing_plan", getPricingPlan, authMiddleware)
e.POST("/user_register", userRegister, authMiddleware)
e.DELETE("/user_delete", userDelete, authMiddleware)
e.GET("/delete_user_log", getDeleteUserLogs, authMiddleware)
e.POST("/self_sign_up", selfSignup, authMiddleware)
e.POST("/logout", logout, authMiddleware)
func authMiddlewareEcho(getter middleware.IDTokenGetter) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
userInfo, err := middleware.Authenticate(c.Request().Context(), getter.GetIDToken(c.Request()))
if err != nil {
http.Error(c.Response().Writer, "Unauthorized "+err.Error(), http.StatusUnauthorized)
return nil
}
c.Set(string(ctxlib.UserInfoKey), userInfo)
return next(c)
}
}
}
# FastAPIの場合、認証用メソッドを作成する
def fastapi_auth(request: Request) -> Union[dict, HTTPException]:
auth_header = request.headers.get("Authorization", "")
token = auth_header.replace("Bearer ", "") if "Bearer " in auth_header else ""
referer = request.headers.get("Referer", "")
user_info, error = auth.authenticate(id_token=token, referer=referer)
if error:
raise HTTPException(status_code=401, detail=str(error))
return user_info
# 認証が必要なルーティングで作成した認証用メソッドをCallする
@app.get("/userinfo")
def get_user_info(user_info: dict = Depends(fastapi_auth)):
return user_info
// IDトークン取得用のメソッドを作成
public static String getIDToken(HttpServletRequest request) {
String authHeader = request.getHeader("Authorization");
if (authHeader != null) {
StringTokenizer st = new StringTokenizer(authHeader);
if (st.countTokens() == 2 && st.nextToken().equalsIgnoreCase("Bearer")) {
return st.nextToken();
}
}
return "";
}
@GetMapping(value = "/userinfo", produces = "application/json")
public ResponseEntity<?> getMe(HttpSession session, HttpServletRequest request) throws Exception {
AuthApiClient apiClient = new Configuration().getAuthApiClient();
apiClient.setReferer(request.getHeader("Referer"));
UserInfoApi userInfoApi = new UserInfoApi(apiClient);
UserInfo userInfo = null;
try {
// 認証が必要な処理を実 行する際に作成したIDトークン取得用のメソッドをCallする
userInfo = userInfoApi.getUserInfo(getIDToken(request));
System.out.println(userInfo);
} catch (ApiException e) {
System.err.println("Exception when calling UserInfoApi#getUserInfo");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
throw e;
}
System.out.println(userInfo.toJson());
return ResponseEntity.ok(userInfo.toJson());
}
// IDトークン取得用のメソッドを作成
string? GetBearerToken(HttpContext context)
{
if (context.Request.Headers.TryGetValue("Authorization", out var authHeader) &&
authHeader.ToString().StartsWith("Bearer "))
{
return authHeader.ToString().Substring("Bearer ".Length).Trim();
}
return null;
}
app.MapGet("/userinfo", async (HttpContext context) =>
{
// 作成したIDトークン取得用のメソッドから取得
var token = GetBearerToken(context);
if (string.IsNullOrEmpty(token))
{
return Results.Unauthorized();
}
try
{
var authApiClientConfig = CreateClientConfiguration(c => c.GetAuthApiClientConfig(), context);
var userInfoApi = new UserInfoApi(authApiClientConfig);
// 取得したIDトークンを利用して、APIをCallする
var userInfo = await userInfoApi.GetUserInfoAsync(token);
var jsonResponse = userInfo.ToJson();
return Results.Text(jsonResponse, "application/json");
}
catch (Exception ex)
{
return HandleApiException(ex);
}
});
// IDトークン取得用のメソッドを作成
private string GetBearerToken(HttpRequestMessage request)
{
// Authorization ヘッダーを確認
var authHeader = request.Headers.Authorization;
// Authorization ヘッダーが存在し、スキームが "Bearer" であることを確認
if (authHeader != null && authHeader.Scheme.Equals("Bearer", StringComparison.OrdinalIgnoreCase))
{
return authHeader.Parameter?.Trim() ?? throw new HttpResponseException(HttpStatusCode.Unauthorized);
}
// Authorization ヘッダーが存在しない場合
throw new HttpResponseException(HttpStatusCode.Unauthorized);
}
[HttpGet]
[Route("userinfo")]
public async Task<IHttpActionResult> GetUserInfo()
{
try
{
// 作成したIDトークン取得用のメソッドから取得
var token = GetBearerToken(Request);
var authApiClientConfig = CreateClientConfiguration(c => c.GetAuthApiClientConfig());
var userInfoApi = new UserInfoApi(authApiClientConfig);
// 取得したIDトークンを利用して、APIをCallする
var userInfo = await userInfoApi.GetUserInfoAsync(token);
return Ok(userInfo);
}
catch (Exception ex)
{
return HandleApiException(ex);
}
}
リフレッシュトークン
ログイン時間を長くする必要がある場合は、リフレッシュトーク ンを使用し、IDトークンを再生成することで、継続的なログインを実現できます。
リフレッシュトークンの有効期限は1ヶ月です。
- PHP
- Node.js
- Go
- Python
- Java
- C#(.Net8)
- C#(.Netfw4.8)
public function refresh(Request $request)
{
// リフレッシュトークンを取得
$refreshToken = $request->cookie('SaaSusRefreshToken');
if (!is_string($refreshToken)) {
return response('Refresh token not found', Response::HTTP_BAD_REQUEST);
}
try {
$authClient = $this->client->getAuthClient();
// 第1引数は一時コードを設定するため、Blankを指定
// 第2引数に認証フローを refreshTokenAuth に設定し、第3引数にCookieから取得したリフレッシュトークンを設定する
$response = $authClient->getAuthCredentials([
'',
'refreshTokenAuth',
$refreshToken
]);
return response()->json($response->getBody());
} catch (\Exception $e) {
return response('Error occurred', Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
app.get('/refresh', async (request: Request, response: Response) => {
// リフレッシュトークンを取得
const refreshToken = request.cookies.SaaSusRefreshToken
if (typeof refreshToken !== 'string') {
response.status(400).send('Refresh token not found')
return
}
const client = new AuthClient()
// 第1引数は一時コードを設定するため、Blankを指定
// 第2引数に認証フローを refreshTokenAuth に設定し、第3引数にCookieから取得したリフレッシュトークンを設定する
const credentials = (
await client.credentialApi.getAuthCredentials(
'',
'refreshTokenAuth',
refreshToken
)
).data
response.send(credentials)
})
func refresh(c echo.Context) error {
// リフレッシュトークンを取得
token, err := c.Cookie("SaaSusRefreshToken")
if err != nil {
return c.String(http.StatusInternalServerError, "internal server error")
}
c.Logger().Error("SaaSusRefreshToken: %v", token.Value)
// 第2引数にCookieから取得したリフレッシュトークンを設定する
credentials, err := credential.GetAuthCredentialsWithRefreshTokenAuth(context.Background(), token.Value)
if err != nil {
return c.String(http.StatusInternalServerError, "internal server error")
}
return c.JSON(http.StatusOK, credentials)
}
@app.get("/refresh")
def refresh(request: Request):
# リフレッシュトークンを取得
saasus_refresh_token = request.cookies.get("SaaSusRefreshToken")
if not saasus_refresh_token:
raise HTTPException(status_code=400, detail="SaaSusRefreshToken is missing")
try:
# リフレッシュトークンを使って新しい認証情報を取得
credentials = callback.get_refresh_token_auth_credentials(saasus_refresh_token)
return credentials
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
// Cookieからリフレッシュトークンを取得
@GetMapping(value = "/refresh", produces = "application/json")
public ResponseEntity<?> refresh(HttpSession session, HttpServletRequest request,
@CookieValue(name = "SaaSusRefreshToken", defaultValue = "") String cookieValue) throws Exception {
if (cookieValue == "") {
return ResponseEntity.badRequest().body("No refresh token found");
}
AuthApiClient apiClient = new Configuration().getAuthApiClient();
apiClient.setReferer(request.getHeader("Referer"));
CredentialApi apiInstance = new CredentialApi(apiClient);
Credentials result = null;
try {
// 第1引数は一時コードを設定するため、nullを指定
// 第2引数に認証フローを refreshTokenAuth に設定し、第3引数にCookieから取得したリフレッシュトークンを設定する
result = apiInstance.getAuthCredentials(null, "refreshTokenAuth", cookieValue);
} catch (ApiException e) {
System.err.println("Exception when calling CredentialApi#getAuthCredentials");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
throw e;
}
return ResponseEntity.ok(result.toJson());
}
app.MapGet("/refresh", async (HttpContext context) =>
{
// Cookieからリフレッシュトークンを取得
var refreshToken = context.Request.Cookies["SaaSusRefreshToken"];
if (string.IsNullOrEmpty(refreshToken))
{
return Results.BadRequest("No refresh token found.");
}
try
{
var authApiClientConfig = CreateClientConfiguration(c => c.GetAuthApiClientConfig(), context);
var credentialApi = new CredentialApi(authApiClientConfig);
// 第1引数は一時コードを設定するため、nullを指定
// 第2引数に認証フローを refreshTokenAuth に設定し、第3引数にCookieから取得したリフレッシュトークンを設定する
var credentials = await credentialApi.GetAuthCredentialsAsync(null, "refreshTokenAuth", refreshToken);
var jsonResponse = credentials.ToJson();
return Results.Text(jsonResponse, "application/json");
}
catch (Exception ex)
{
return HandleApiException(ex);
}
});
[HttpGet]
[Route("refresh")]
public async Task<IHttpActionResult> Refresh()
{
try
{
// Cookieからリフレッシュトークンを取得
var refreshTokenCookie = Request.Headers.GetCookies("SaaSusRefreshToken").FirstOrDefault();
if (refreshTokenCookie == null)
{
return BadRequest("No refresh token found.");
}
var authApiClientConfig = CreateClientConfiguration(c => c.GetAuthApiClientConfig());
var credentialApi = new CredentialApi(authApiClientConfig);
// 第1引数は一時コードを設定するため、nullを指定
// 第2引数に認証フローを refreshTokenAuth に設定し、第3引数にCookieから取得したリフレッシュトークンを設定する
var credentials = await credentialApi.GetAuthCredentialsAsync(null, "refreshTokenAuth", refreshTokenCookie["SaaSusRefreshToken"].Value);
return Ok(credentials);
}
catch (Exception ex)
{
return HandleApiException(ex);
}
}
アクセストークン
アクセストークンは、認可が必要な機能を利用する際に必要となるトークンです。
例えば、テナントへのユーザー招待機能など、特定の権限が求められる機能で使用されます。
- PHP
- Node.js
- Go
- Python
- Java
- C#(.Net8)
- C#(.Netfw4.8)
// リクエストから情報を取得
$email = $request->input('email');
$tenantId = $request->input('tenantId');
if (!$email || !$tenantId) {
return response()->json(['message' => 'Missing required fields'], Response::HTTP_BAD_REQUEST);
}
// UserInfo を取得
$userInfo = $request->userinfo;
if (!$userInfo) {
return response()->json(['detail' => 'No user'], Response::HTTP_BAD_REQUEST);
}
try {
// 招待を作成するユーザーのアクセストークンを取得
$accessToken = $request->header('X-Access-Token');
// アクセストークンがリクエストヘッダーに含まれていなかったらエラー
if (empty($accessToken)) {
return response()->json(['error' => 'Access token is missing'], 401);
}
// テナント招待のパラメータを作成
$createTenantInvitationParamEnvsItem = new CreateTenantInvitationParamEnvsItem();
$createTenantInvitationParamEnvsItem
->setId(3) // 本番環境のid:3を指定
->setRoleNames(['admin']);
$createTenantInvitationParam = new CreateTenantInvitationParam();
$createTenantInvitationParam
->setEmail($email)
->setAccessToken($accessToken)
->setEnvs([$createTenantInvitationParamEnvsItem]);
// テナント招待のAPIをCallする
$authClient = $this->client->getAuthClient();
$authClient->createTenantInvitation(
$tenantId,
$createTenantInvitationParam
);
return response()->json(['message' => 'Create tenant user invitation successfully']);
} catch (\Exception $e) {
Log::error($e->getMessage());
return response()->json(['detail' => $e->getMessage()], Response::HTTP_INTERNAL_SERVER_ERROR);
}
const { email, password, tenantId, userAttributeValues }: UserRegisterRequest = request.body
if (!email || !password || !tenantId) {
return response.status(400).send({ message: 'Missing required fields' });
}
const userInfo = request.userInfo
if (userInfo === undefined) {
return response.status(400).json({ detail: 'No user' })
}
try {
// 招待を作成するユーザーのアクセストークンを取得
const accessToken = request.header('X-Access-Token')
// アクセストークンがリクエストヘッダーに含まれていなかったらエラー
if (!accessToken) {
return response.status(401).json({ detail: 'Access token is missing' })
}
// テナント招待のパラメータを作成
const invitedUserEnvironmentInformationInner: InvitedUserEnvironmentInformationInner = {
id: 3, // 本番環境のid:3を指定
role_names: ['admin']
}
const createTenantInvitationParam: CreateTenantInvitationParam = {
email: email,
access_token: accessToken,
envs: [invitedUserEnvironmentInformationInner]
}
// テナントへの招待を作成
const client = new AuthClient()
await client.invitationApi.createTenantInvitation(tenantId, createTenantInvitationParam)
response.json({ message: 'Create tenant user invitation successfully' })
} catch (error) {
console.error(error);
response.status(500).json({ detail: error });
}
var request UserRegisterRequest
if err := c.Bind(&request); err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"error": "Invalid request"})
}
email := request.Email
tenantID := request.TenantID
userInfo, ok := c.Get(string(ctxlib.UserInfoKey)).(*authapi.UserInfo)
if !ok {
c.Logger().Error("failed to get user info")
return c.String(http.StatusInternalServerError, "internal server error")
}
// 招待を作成するユーザーのアクセストークンを取得
accessToken := c.Request().Header.Get("X-Access-Token")
// アクセストークンがリクエストヘッダーに含まれていなかったらエラー
if accessToken == "" {
return c.String(http.StatusBadRequest, "Access token is missing")
}
// テナント招待のパラメータを作成
createTenantInvitationJSONRequestBody := authapi.CreateTenantInvitationJSONRequestBody{
AccessToken: accessToken,
Email: email,
Envs: []struct {
Id uint64 `json:"id"`
RoleNames []string `json:"role_names"`
}{
{
Id: 3, // 本番環境のid:3を指定
RoleNames: []string{"admin"},
},
},
}
// テナントへの招待を作成
authClient.CreateTenantInvitation(context.Background(), tenantID, createTenantInvitationJSONRequestBody)
return c.JSON(http.StatusOK, echo.Map{"message": "Create tenant user invitation successfully"})
# リクエストデータの取得
email = request.email
tenant_id = request.tenantId
# ユーザー登録処理
try:
# 招待を作成するユーザーのアクセストークンを取得
access_token = fast_request.headers.get("X-Access-Token")
# アクセストークンがリクエストヘッダーに含まれていなかったらエラー
if not access_token:
raise HTTPException(status_code=401, detail="Access token is missing")
# テナント招待のパラメータを作成
invited_user_environment_information_inner = InvitedUserEnvironmentInformationInner(
id=3, # 本番環境のid:3を指定
role_names=['admin']
)
create_tenant_invitation_param = CreateTenantInvitationParam(
email=email,
access_token=access_token,
envs=[invited_user_environment_information_inner]
)
# テナントへの招待を作成
InvitationApi(api_client=api_client).create_tenant_invitation(tenant_id=tenant_id, create_tenant_invitation_param=create_tenant_invitation_param)
return {"message": "Create tenant user invitation successfully"}
except Exception as e:
print(e)
raise HTTPException(status_code=500, detail=str(e))
try {
String email = requestBody.getEmail();
String tenantId = requestBody.getTenantId();
AuthApiClient apiClient = new Configuration().getAuthApiClient();
apiClient.setReferer(request.getHeader("Referer"));
UserInfoApi userInfoApi = new UserInfoApi(apiClient);
UserInfo userInfo = userInfoApi.getUserInfo(getIDToken(request));
// リクエストヘッダーからアクセストークンを取得する
String accessToken = request.getHeader("X-Access-Token");
// アクセストークンがリクエストヘッダーに含まれていなかったらエラー
if (accessToken == null || accessToken.isEmpty()) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Access token is missing");
}
// テナント招待のパラメータを作成
InvitedUserEnvironmentInformationInner invitedUserEnvironmentInformationInner = new InvitedUserEnvironmentInformationInner()
.id(3) // 本番環境のid:3を指定
.addRoleNamesItem("admin");
CreateTenantInvitationParam createTenantInvitationParam = new CreateTenantInvitationParam()
.email(email)
.accessToken(accessToken)
.addEnvsItem(invitedUserEnvironmentInformationInner);
// テナントへの招待を作成
InvitationApi invitationApi = new InvitationApi(apiClient);
invitationApi.createTenantInvitation(tenantId, createTenantInvitationParam);
Map<String, String> successResponse = new HashMap<>();
successResponse.put("message", "Create tenant user invitation successfully");
return ResponseEntity.ok(successResponse);
} catch (ApiException e) {
System.err.println("API Exception: " + e.getMessage());
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "API Exception: " + e.getMessage(), e);
} catch (Exception e) {
System.err.println("Unexpected Exception: " + e.getMessage());
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Unexpected Exception: " + e.getMessage(), e);
}
var validationResults = new List<ValidationResult>();
var validationContext = new ValidationContext(requestBody);
if (!Validator.TryValidateObject(requestBody, validationContext, validationResults, true))
{
var errors = validationResults.Select(vr => new { Field = vr.MemberNames.FirstOrDefault(), Error = vr.ErrorMessage });
return Results.BadRequest(new { error = "Validation failed.", details = errors });
}
string email = requestBody.Email;
string tenantId = requestBody.TenantId;
try
{
// 招待を作成するユーザーのアクセストークンを取得
var accessToken = context.Request.Headers["X-Access-Token"].FirstOrDefault();
// アクセストークンがリクエストヘッダーに含まれていなかったらエラー
if (string.IsNullOrEmpty(accessToken))
{
return Results.Unauthorized();
}
var authApiClientConfig = CreateClientConfiguration(c => c.GetAuthApiClientConfig(), context);
var invitationApi = new InvitationApi(authApiClientConfig);
// envsに追加するオブジェクトを作成
var invitedEnv = new InvitedUserEnvironmentInformationInner(
id: 3, // 本番環境のid:3を指定
roleNames: new List<string> { "admin" }
);
// envsのリストを作成
var envsList = new List<InvitedUserEnvironmentInformationInner> { invitedEnv };
// テナント招待のパラメータを作成
var createTenantInvitationParam = new CreateTenantInvitationParam(
email,
accessToken,
envsList
);
// テナントへの招待を作成
invitationApi.CreateTenantInvitation(tenantId, createTenantInvitationParam);
return Results.Ok(new { message = "Create tenant user invitation successfully" });
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error: {ex.Message}");
return Results.Problem(detail: ex.Message, statusCode: 500);
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
string email = request.Email;
string tenantId = request.TenantId;
try
{
// 招待を作成するユーザーのアクセストークンを取得
var accessToken = HttpContext.Current.Request.Headers.Get("X-Access-Token");
var authApiClientConfig = CreateClientConfiguration(c => c.GetAuthApiClientConfig());
var invitationApi = new InvitationApi(authApiClientConfig);
// envsに追加するオブジェクトを作成
var invitedEnv = new InvitedUserEnvironmentInformationInner(
id: 3, // 本番環境のid:3を指定
roleNames: new List<string> { "admin" }
);
// envsのリストを作成
var envsList = new List<InvitedUserEnvironmentInformationInner> { invitedEnv };
// テナント招待のパラメータを作成
var createTenantInvitationParam = new CreateTenantInvitationParam(
email,
accessToken,
envsList
);
// 非同期メソッドを使用する場合(CreateTenantInvitationが非同期の場合)
invitationApi.CreateTenantInvitation(tenantId, createTenantInvitationParam);
// 結果を返す
return Ok(new { message = "Create tenant user invitation successfully", request });
}
catch (Exception ex)
{
return HandleApiException(ex);
}