Skip to content

Commit

Permalink
Merge pull request #38 from mainmethod0126/lets-try-using-the-grpc-ja…
Browse files Browse the repository at this point in the history
…va-library

Lets try using the grpc java library
  • Loading branch information
mainmethod0126 authored Nov 18, 2024
2 parents f3c6d21 + 5af3edb commit 05abbf6
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 0 deletions.
1 change: 1 addition & 0 deletions pages/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"jpa": "jpa",
"serialized-data-structure": "serialized data structure",
"webRTC": "webRTC",
"electron": "electron",
"etc": "etc",
"tistory": {
"title": "Tistory Blog ↗",
Expand Down
35 changes: 35 additions & 0 deletions pages/electron/main-preload-renderer.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 일렉트론의 main 프로세스, renderer 프로세스, preload 스크립트

## 프로레스 모델 분리

- 크게 **main 프로세스****renderer 프로세스** 두 가지 유형의 프로세스가 존재

### Main

- 일렉트론 앱에는 필수적으로 **단일 main 프로세스**가 존재함
- 모든 Node.js API 를 사용할 수 있음
- `BrowserWindow` 모듈을 사용해 window 를 만들고 관리하는게 주 목적
- **BrowserWindow 인스턴스**가 제거되면 해당 renderer 프로세스도 종료된다
- `app` 모듈을 통해서 어플리케이션의 생명 주기를 제어한다

### Renderer

- `renderer 프로세스`는 웹 컨텐츠를 렌더링하는 역할을 한다
- 일렉트론 앱은 각 `BrowserWindow`에 대해 **별도의 renderer 프로세스를 생성**
- 보안 이유로 `Node.js` 를 바로 사용할 수 없다

### Preload 스크립트

- 웹 컨텐츠가 로드되기 전에 렌더러 프로세스에서 실행되는 코드가 포함되어 있다
- `BrowserWindow 생성자``webPreferences` 옵션을 통해 main 프로세스에 preload 스크립트를 연결할 수 있다
- `preload 스크립트`**전역 window 인터페이스****renderer와 공유**한다
- `contextIsolation 기본값` 때문에 preload 스크립트에서 window로 변수를 직접 연결할 수 없다
- `컨텍스트 격리(Context Isolation)`는 preload 스크립트와 일렉트론의 내부 로직이 webContents에 로드된 웹 사이트에 별도의 컨텍스트에서 실행되도록 하는 기능이다
- 웹 사이트가 일렉트론 내부 또는 preload 스크립트에 접근하지 못하도록 하기 때문에 보안 목적으로 중요하다
- 컨텍스트 격리를 통해 preload 스크립트 내 권한을 가진 API가 웹 컨텐츠 코드로 유출되지 않도록 한다.

---

## 프로세스 간 통신

- 프로세스 간 통신을 위해 **IPC(Inter-Process Communication)**를 사용한다
107 changes: 107 additions & 0 deletions pages/java/lets-try-using-the-grpc-java-library.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# grpc-java 라이브러리를 사용해보자

일단 grpc 용어좀 짚고가자

## 채널 channel

- **네트워크 연결 관리** : 클라이언트와 서버간의 연결
- **보안** : TLS/SSL 을 통한 보안 통신 가능
- **상태 모니터링** : 채널은 서버 연결 상태(예: IDLE, CONNECTING, READY, TRANSIENT_FAILURE, SHUTDOWN)를 관리하고, 클라이언트가 이 상태를 추적할 수 있게 해줌

### 채널의 생성과 관리

채널은 한번 생성하면 재사용하는게 일반적임,
**재사용도 다 하고 이제 쓸일 없으면 닫아야함**


채널의 생성
```java
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
.usePlaintext() // TLS를 적용하려면 .useTransportSecurity()를 사용
.build();
```

채널 닫기
```java
channel.shutdown();
```

## 스텁 stub

**"메소드 스텁(method stub) 혹은 간단히 스텁은 소프트웨어 개발에 쓰이고 다른 프로그래밍 기능을 대리하는 코드이다"
서버에 있는 함수가 Client에는 없으니까 `서버의 함수를 호출하듯이 서버 함수를 대신해주는 대신맨` **


### 동기 스텁 (blocking stub)
동기 방식의 호출을 수행하며, 서버의 응답을 받을 때까지 클라이언트는 호출이 완료될 때까지 대기합니다.
`예: HelloServiceGrpc.HelloServiceBlockingStub`

### 비동기 스텁 (future stub)
비동기 방식으로 Future 객체를 반환합니다. 응답을 즉시 기다릴 필요 없이 비동기 작업으로 처리할 수 있습니다.
`예: HelloServiceGrpc.HelloServiceFutureStub`

### 콜백 스텁 (async stub)
비동기 방식으로 Future 객체를 반환합니다. 응답을 즉시 기다릴 필요 없이 비동기 작업으로 처리할 수 있습니다.
`예: HelloServiceGrpc.HelloServiceFutureStub`

### 스텁의 생성 및 사용

```java
HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub(channel);

HelloRequest request = HelloRequest.newBuilder()
.setName("ChatGPT")
.build();

HelloResponse response = stub.sayHello(request);
System.out.println("서버 응답: " + response.getMessage());
```


---

## grpc client 에서 jwt 포함하여 호출하기


```java
public class JwtCallCredentials extends CallCredentials {
private final String jwt;

public JwtCallCredentials(String jwt) {
this.jwt = jwt;
}

@Override
public void applyRequestMetadata(RequestInfo requestInfo,
Executor appExecutor,
MetadataApplier applier) {
appExecutor.execute(() -> {
try {
Metadata headers = new Metadata();
headers.put(
Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER),
"Bearer " + jwt);
applier.apply(headers);
} catch (Throwable e) {
applier.fail(Status.UNAUTHENTICATED.withCause(e));
}
});
}
}

```
```java
public HelloWorldClient(Channel channel, CallCredentials callCredentials) {
blockingStub = GreeterGrpc.newBlockingStub(channel).withCallCredentials(callCredentials);
}
```
```java
HelloWorldClient client = new HelloWorldClient(channel, new JwtCallCredentials("asdadsad"));
client.greet(user);
```






78 changes: 78 additions & 0 deletions pages/spring/try-using-oauth2-in-spring-security-6x.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# spring security 6.x 버전에서 oauth2 사용해보기

## 1. OAuth2AuthorizationRequestRedirectFilter 를 통한 필터링

`http://localhost:8080/oauth2/authorization/google` 로 들어온 요청을 캐치해서

config 에 정의된 `redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"` 로 리다이렉트 시킨다, `response.sendRedirect(redirectUrl);` 이렇게 리스폰스 객체로 바로 리다이렉트 보내버림


## 2. OAuth2LoginAuthenticationFilter 를 통한 인증 처리

`Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)` 함수에서 인증 처리가 진행됨

- 사용자 요청을 `OAuth2AuthorizationRequest authorizationRequest` 로 만듬
- `authorizationRequest` 를 이용해 `OAuth2LoginAuthenticationToken authenticationRequest` 를 만듬
```
OAuth2LoginAuthenticationToken authenticationResult = (OAuth2LoginAuthenticationToken) this
.getAuthenticationManager()
.authenticate(authenticationRequest);
```
- 위와 같이 `getAuthenticationManager` 를 이용하여 인증을 진행하여 `OAuth2LoginAuthenticationToken authenticationResult` 를 만들어냄


인증 완료되면 기본값으로 `"/"` path 로 리다이렉트 함, 그런데 서버가 `localhost:8080` 으로 동작 중이고, 웹 페이지가 `localhost:3000` 에서 동작중이면,
`localhost:8080/` 로 리다이렉트되기 때문에 `/` 요청이 왔을 경우 로그인 요청이 왔던 `Referer` 주소로 리다이렉트 시켜줘야함

이는 별도의 복잡한 코딩없이

`successHandler.setUseReferer(true);` 만 해주면 요청했던 주소로 리다이렉트 됨

```java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

private AuthenticationSuccessHandler getSuccessHandler() {
var successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setUseReferer(true);
return successHandler;
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

http
.authorizeHttpRequests(authorizeRequests -> authorizeRequests
.anyRequest().authenticated())
.oauth2Login(httpSecurity -> httpSecurity.successHandler(getSuccessHandler()));

return http.build();
}
}
```

코드를 직접 타고가면서 확인한 로직,

`AbstractAuthenticationTargetUrlRequestHandler` 클래스의 아래 함수를 보면 알 수 있음

```java
/**
* Builds the target URL according to the logic defined in the main class Javadoc.
*/
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
if (isAlwaysUseDefaultTargetUrl()) {
return this.defaultTargetUrl;
}
String targetUrlParameterValue = getTargetUrlParameterValue(request);
if (StringUtils.hasText(targetUrlParameterValue)) {
trace("Using url %s from request parameter %s", targetUrlParameterValue, this.targetUrlParameter);
return targetUrlParameterValue;
}
if (this.useReferer) {
trace("Using url %s from Referer header", request.getHeader("Referer"));
return request.getHeader("Referer");
}
return this.defaultTargetUrl;
}
```
3 changes: 3 additions & 0 deletions theme.config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ const config: DocsThemeConfig = {
if (title === "webRTC") {
return <>📒 {title}</>;
}
if (title === "electron") {
return <>📒 {title}</>;
}
if (title === "etc") {
return <>📒 {title}</>;
}
Expand Down

0 comments on commit 05abbf6

Please sign in to comment.