유니티에서 gRPC 사용하기 3 - ASP.NET 인증서버 구성
gRPC + MySQL/Dapper 인증서버
개요
ASP.NET과 유니티가 실제로 인증서버를 기반으로 통신하기 위해 MySQL과 gRPC를 통해서 먼저 서버를 구성하는 과정을 거쳤다.
1) 프로젝트 생성
Visual Studio에서 기본적으로 gRPC관련 템플릿을 제공하는게 있다. ASP.NET Core gRPC 템플릿을 선택해 기본 프로젝트를 생성했다.
2) Proto 설정 및 설계 - 단항 RPC
우선은 기본적으로 .proto 파일을 생성한후 아래와 같이 설정해주었다.
Build Action
protoc(컴파일러)
는.proto
파일을 확인해서 C# 코드가 생성이된다. 따라서 이를 설정해 준것이다.
복잡한 로직이 아니라 단순히 회원가입이나 로그인만을 처리할 것이므로 단항 RPC로만 구성을 했다. Register / Login / DeleteAccount 3가지 RPC만 만들어 주었다. 사실 인증서버 만드는게 처음이라서 이 경우 말고도 고려를 해야할게 있나 싶은데, 일단은 이렇게 구성을 해보았다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
syntax = "proto3";
// 네임스페이스 설정
package Auth;
option csharp_namespace = "Auth";
service Accounts
{
// rpc [함수이름] (~~) 데이터를 받고, returns (~~) 데이터를 반환
rpc Register (RegisterRequest) returns (RegisterResponse);
rpc Login (LoginRequest) returns (LoginResponse);
rpc DeleteAccount (DeleteAccountRequest) returns (DeleteAccountResponse);
}
message RegisterRequest {
string username = 1;
string id = 2;
string password = 3;
}
message RegisterResponse {
bool success = 1;
string message = 2;
}
message LoginRequest {
string username = 1;
string password = 2;
}
message LoginResponse {
bool success = 1;
string message = 2;
string token = 3;
}
message DeleteAccountRequest {
string username = 1;
string password = 2;
}
message DeleteAccountResponse {
bool success = 1;
string message = 2;
}
3) NuGet 패키지 설치 - Dapper, MySql.Data
NuGet 패키지 관리자로 두가지 패키지를 설치했다.
- Dapper: 경량 Micro ORM으로 C# 코드에서 MySQL 데이터베이스와 직접 연결할 수 있도록 해주는 드라이버 역할을한다. - 그냥 SQL 문법을 C#에서 곧바로 작성하는거다.
- MySql.Data: 공식으로 지원하는 MySQL과 .Net을 연결해주는 커넥터이다.
4) DB 연결설정 - appsettings.Development.json
개발 환경 설정 파일에 DB 연결 문자열의 비밀번호를 지정한다.
appsettings.json 파일자체에다가 비밀번호를 설정하고나서 github같은 곳에 올리게 되면 해킹의 위험이 있다고 한다! 물론 지금은 간단하게 서버를 구성하는 것이라 상관은 없지만 이런 위험이 있다고 하니 알아두자!
5) DB 유저 테이블 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
DROP TABLE Users;
CREATE TABLE `Users` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`userId` VARCHAR(100) NOT NULL,
`PasswordHash` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `username_UNIQUE` (`username` ASC),
UNIQUE INDEX `userId_UNIQUE` (`userId` ASC)
);
SELECT * FROM user_db.users;
6) gRPC 서비스 구현 및 등록
아까전에 작성한 .proto 파일이 자동으로 코드를 생성해준다. 이렇게 생성된 Accounts. AccountsBase 클래스를 나의 서비스에 상속을 받게 해준다. 이제 여기다가 로직적인 부분을 작성해주면 된다.
구현한 서비스를 gRPC 파이프라인에 등록을 하는과정을 거쳐야 나의 서비스 로직이 동작할수 있다. main 함수에서 AddSinglton() 을 통해서 등록을 해주었다.
서비스 로직 요약
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/// <summary>
/// 회원가입 처리
/// </summary>
public override async Task<RegisterResponse> Register(RegisterRequest request, ServerCallContext context)
{
try
{
// mysql 연결
await using var connection = new MySqlConnection(_connectionString);
await connection.OpenAsync();
// 유저데이터 생성 - 입력검증
var createResult = TryCreateUser(request);
if (createResult.IsSuccess == false)
return RegisterResponse.Custom_Fail(createResult.ErrorMessage);
// 사용자 중복 확인
var userExistsResult = await IsUserExistsAsync(connection, createResult.Value.Username, createResult.Value.ID);
if (userExistsResult.IsSuccess == false)
return RegisterResponse.Custom_Fail(userExistsResult.ErrorMessage);
// 데이터베이스에 사용자 생성
await CreateUserAsync(connection, createResult.Value);
// 최종 성공 응답 반환
return RegisterResponse.Custom_Success();
}
catch (Exception ex)
{
Console.WriteLine(ex);
return RegisterResponse.Custom_Fail("서버 내부 오류가 발생했습니다.");
}
}
/// <summary>
/// 로그인 처리
/// </summary>
public override async Task<LoginResponse> Login(LoginRequest request, ServerCallContext context) { ... }
/// <summary>
/// 회원 탈퇴 처리
/// </summary>
public override async Task<DeleteAccountResponse> DeleteAccount(DeleteAccountRequest request, ServerCallContext context)
{ ... }
마무리
서버 측 구성은 일단 여기까지이며, 이제 유니티 쪽에서 클라이언트 로직을 작성해주면 된다.