Spring Boot で Google ログインを付けるには、spring-boot-starter-security-oauth2-client を入れて、application.yml に Google の client-id と client-secret を書きます。 これだけで、ログインしていない人は自動で Google の画面に送られ、ログイン後にアプリへ戻ってきます。Google Cloud コンソールには、リダイレクト URI として http://localhost:8080/login/oauth2/code/google を登録します。

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: ${GOOGLE_CLIENT_ID}
            client-secret: ${GOOGLE_CLIENT_SECRET}
やること 場所 値
OAuth クライアント ID を作る Google Cloud コンソール 種類は「ウェブ アプリケーション」
リダイレクト URI を登録 同上「承認済みのリダイレクト URI」 http://localhost:8080/login/oauth2/code/google
依存を足す build.gradle.kts spring-boot-starter-security-oauth2-client
ID とシークレットを書く application.yml 上のとおり(環境変数から読む)
画面を守る・ログアウト SecurityFilterChain 下の完成コード

確認環境:Spring Boot 4.1.1・Spring Security 7.1.1(Spring Framework 7.0.9)。Google 用の既定値(スコープ・エンドポイント)、リダイレクト URI の形、エラーコードとメッセージ、Boot の自動設定は、Spring Security 7.1.1 と Spring Boot v4.1.1 のソース(GitHub のタグ)で確かめました。Google 側のエラーと ID トークンの項目は Google for Developers のドキュメントで確かめています(確認日 2026年10月13日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Spring BootでGoogleログイン|OAuth2 Clientの完成コード」

しくみ:どこからどこへ移動するか

Google ログインは、OpenID Connect(OAuth 2.0 の上に「誰がログインしたか」を伝える部分を足した仕様)の「認可コードフロー」で動きます。

  1. ブラウザが / を開く。ログインしていないので /oauth2/authorization/google へ移る
  2. Spring がランダムな state(なりすまし防止の値)と nonce を作ってセッションに保存し、Google の認可画面(https://accounts.google.com/o/oauth2/v2/auth)へ移す
  3. 利用者が Google でログインし、同意する
  4. Google が /login/oauth2/code/google?code=…&state=… へ戻す(これがリダイレクト URI)
  5. Spring が state を照合し、code をトークンエンドポイントへ送って ID トークンとアクセストークンを受け取る
  6. ID トークンの署名・発行者・宛先・nonce を確かめ、ログイン済みにする

OAuth 2.0 と OpenID Connect の違いは、関連記事「OAuth 2.0とOpenID Connectの違いをわかりやすく解説」で扱っています。

Google 用の既定値(Spring Security 7.1.1 のソース)

registration の名前を google にすると、Spring Security の CommonOAuth2Provider.GOOGLE の値が自動で入ります。そのため client-id と client-secret だけで動きます。

項目 既定値
スコープ openid・profile・email
認可エンドポイント https://accounts.google.com/o/oauth2/v2/auth
トークンエンドポイント https://www.googleapis.com/oauth2/v4/token
公開鍵(JWK Set) https://www.googleapis.com/oauth2/v3/certs
発行者(issuer) https://accounts.google.com
ユーザー情報 https://www.googleapis.com/oauth2/v3/userinfo
ユーザー名に使う項目 sub
クライアント認証 client_secret_basic(Basic 認証ヘッダーで送る)
リダイレクト URI {baseUrl}/{action}/oauth2/code/{registrationId}
画面の表示名 Google

リダイレクト URI の {action} は、ログインでは login になります。{registrationId} は application.yml の registration の下に書いた名前です。名前を google-login などに変えると、リダイレクト URI も /login/oauth2/code/google-login に変わります。 そのときは provider: google を足します(足さないと下の「起動時のエラー」になります)。

Google Cloud コンソールの設定

  1. Google Cloud コンソールでプロジェクトを選ぶ
  2. 「Google Auth Platform」(旧「OAuth 同意画面」)で、アプリ名・サポートメール・対象(内部/外部)を設定する
  3. 「クライアント」で「クライアントを作成」→ 種類「ウェブ アプリケーション」
  4. 「承認済みのリダイレクト URI」に、環境ごとに URI を登録する
  5. 表示されたクライアント ID とクライアント シークレットを控える
環境 登録するリダイレクト URI
手元 http://localhost:8080/login/oauth2/code/google
本番 https://app.example.com/login/oauth2/code/google
コンテキストパスあり https://example.com/myapp/login/oauth2/code/google

Google のドキュメントでは、リダイレクト URI には次の決まりがあります。

  • https であること(localhost と localhost の IP アドレスは例外)
  • ホストに IP アドレスは使えない(localhost の IP アドレスは例外)
  • トップレベルドメインが公開サフィックスリストにあること

localhost と 127.0.0.1 は別の URI として扱われます。 ブラウザで開いたほうと同じものを登録します。

完成コード

依存(build.gradle.kts)

plugins {
    java
    id("org.springframework.boot") version "4.1.1"
    id("io.spring.dependency-management") version "1.1.7"
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-webmvc")
    implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
    implementation("org.springframework.boot:spring-boot-starter-security-oauth2-client")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    runtimeOnly("org.postgresql:postgresql")
}

Boot 4.1.1 のソースでは、Boot 3 までの spring-boot-starter-oauth2-client は「spring-boot-starter-security-oauth2-client に置き換えられた(deprecated)」と説明されています。中身の依存は同じです。starter の新旧の対応は、関連記事「Spring Boot starter一覧|用途別の選び方とBoot 4の新旧対応表」で扱っています。

application.yml

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: ${GOOGLE_CLIENT_ID}
            client-secret: ${GOOGLE_CLIENT_SECRET}
            # scope を書くと既定(openid, profile, email)を置き換える
            # scope: openid, profile, email

server:
  # リバースプロキシ(nginx・ロードバランサー)の後ろで https を正しく扱う
  forward-headers-strategy: native

logging:
  level:
    # ログイン失敗の本当の理由を見るとき
    org.springframework.security: DEBUG

client-secret はリポジトリに書かず、環境変数などから渡します。プロファイルごとの設定の分け方は、関連記事「Spring Bootプロファイル切り替え|application.ymlと優先順位」で扱っています。

SecurityFilterChain

package com.example.auth;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http,
                                            ClientRegistrationRepository repo,
                                            AppOidcUserService oidcUserService) throws Exception {
        // Google の画面に毎回アカウント選択を出す
        var resolver = new DefaultOAuth2AuthorizationRequestResolver(
                repo, OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI);
        resolver.setAuthorizationRequestCustomizer(
                c -> c.additionalParameters(p -> p.put("prompt", "select_account")));

        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/", "/login", "/error", "/css/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated())
            .oauth2Login(o -> o
                .loginPage("/login")                                   // 自前のログイン画面
                .authorizationEndpoint(a -> a.authorizationRequestResolver(resolver))
                .userInfoEndpoint(u -> u.oidcUserService(oidcUserService)) // DB と紐づける
                .defaultSuccessUrl("/home", true)
                .failureHandler((req, res, ex) -> {
                    String code = (ex instanceof OAuth2AuthenticationException oae)
                            ? oae.getError().getErrorCode() : "unknown";
                    res.sendRedirect("/login?error=" + code);
                }))
            .logout(l -> l
                .logoutSuccessUrl("/?logout")
                .deleteCookies("JSESSIONID"));
        return http.build();
    }
}

SecurityFilterChain を自分で定義すると、Boot の自動設定(OAuth2ClientWebSecurityAutoConfiguration)の分は作られなくなります。自動設定の中身は、v4.1.1 のソースでは「すべてのリクエストに認証を求め、oauth2Login と oauth2Client を既定で有効にする」だけです。SecurityFilterChain の基本は、関連記事「Spring Security入門|SecurityFilterChainとDB認証」で扱っています。

failureHandler を書くのには理由があります。 Spring Security 7.1.1 の既定のログイン画面(DefaultLoginPageGeneratingFilter)は、失敗したとき理由にかかわらず Invalid credentials とだけ表示します。上のように getErrorCode() を取り出すと、下の「よくあるエラー」の表で原因を引けます。

ユーザー情報の取り出し

Google ログイン(openid スコープあり)では、ログインした人は OidcUser になります。

package com.example.web;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @GetMapping("/home")
    public String home(@AuthenticationPrincipal OidcUser user, Model model) {
        model.addAttribute("sub", user.getSubject());          // Google のユーザー ID(変わらない)
        model.addAttribute("email", user.getEmail());
        model.addAttribute("verified", user.getEmailVerified());
        model.addAttribute("name", user.getFullName());
        model.addAttribute("picture", user.getPicture());
        model.addAttribute("hd", user.getClaimAsString("hd"));  // Google Workspace のドメイン
        return "home";
    }
}

Google のドキュメントにある、ID トークンの主な項目です。

項目 取り出し方 いつ入るか
sub getSubject() いつも。Google アカウントごとに一意で、再利用されない
email getEmail() email スコープのとき。一意とは限らず、変わることもある
email_verified getEmailVerified() email スコープのとき
name getFullName() 必ず入るとは限らない(profile スコープ)
given_name / family_name getGivenName() / getFamilyName() 同上
picture getPicture() 同上
locale getLocale() 同上
hd getClaimAsString("hd") Google Workspace などの組織のアカウントのときだけ

Google のドキュメントでは「email をユーザーを見分けるキーに使わず、sub を使う」と書かれています。 DB でユーザーを探すときも sub を使います。

Thymeleaf の画面では、sec:authentication を使わなくても、上のように Model に入れて表示できます。

<!-- templates/home.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
  <img th:if="${picture}" th:src="${picture}" width="48" height="48" alt="">
  <p th:text="${name} + ' さん'">名前</p>
  <p th:text="${email}">メール</p>
  <form th:action="@{/logout}" method="post">
    <button type="submit">ログアウト</button>
  </form>
</body>
</html>
<!-- templates/login.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
  <p th:if="${param.error}" th:text="'ログインできませんでした(' + ${param.error} + ')'"></p>
  <p th:if="${param.logout}">ログアウトしました</p>
  <a th:href="@{/oauth2/authorization/google}">Google でログイン</a>
</body>
</html>

ログインのリンク先は /oauth2/authorization/google です(google は registration の名前)。Thymeleaf の属性は、関連記事「Thymeleafの使い方|th:each・th:ifなど属性一覧と出力例」で扱っています。

DB のユーザーと紐づける

ログインのたびに、sub で自分の DB のユーザーを探し、無ければ作ります。あわせて、DB の権限(ロール)をログインした人に付けます。

package com.example.auth;

import jakarta.persistence.*;
import java.time.Instant;

@Entity
@Table(name = "app_user",
       uniqueConstraints = @UniqueConstraint(columnNames = {"provider", "provider_subject"}))
public class AppUser {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false) private String provider;              // "google"
    @Column(name = "provider_subject", nullable = false) private String providerSubject; // sub
    private String email;
    private String displayName;
    @Column(nullable = false) private String role = "USER";
    private Instant lastLoginAt;

    protected AppUser() {}
    public AppUser(String provider, String providerSubject) {
        this.provider = provider;
        this.providerSubject = providerSubject;
    }
    // getter・setter は省略
}
package com.example.auth;

import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface AppUserRepository extends JpaRepository<AppUser, Long> {
    Optional<AppUser> findByProviderAndProviderSubject(String provider, String providerSubject);
}
package com.example.auth;

import java.time.Instant;
import java.util.List;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class AppOidcUserService extends OidcUserService {

    private final AppUserRepository users;

    public AppOidcUserService(AppUserRepository users) {
        this.users = users;
    }

    @Override
    @Transactional
    public OidcUser loadUser(OidcUserRequest request) throws OAuth2AuthenticationException {
        OidcUser google = super.loadUser(request);       // ID トークンとユーザー情報を取る

        // 例:社内ドメインだけ許可する(hd は ID トークンで確かめる)
        if (!"example.com".equals(google.getClaimAsString("hd"))) {
            throw new OAuth2AuthenticationException(new OAuth2Error("domain_not_allowed"));
        }

        String provider = request.getClientRegistration().getRegistrationId(); // "google"
        AppUser user = users.findByProviderAndProviderSubject(provider, google.getSubject())
                .orElseGet(() -> new AppUser(provider, google.getSubject()));
        user.setEmail(google.getEmail());
        user.setDisplayName(google.getFullName());
        user.setLastLoginAt(Instant.now());
        users.save(user);

        var authorities = List.of(new SimpleGrantedAuthority("ROLE_" + user.getRole()));
        return new DefaultOidcUser(authorities, google.getIdToken(), google.getUserInfo(), "sub");
    }
}
決めごと 理由
provider と sub の組で一意にする 後から GitHub などを足しても、ID がぶつからない
メールアドレスで探さない Google のドキュメントで、メールは一意とは限らず変わりうるとされている
権限は DB から付ける Google の情報には、アプリの権限は入っていない
ドメインの制限は hd をサーバーで確かめる 認可リクエストに hd を付けても、それは画面の候補をしぼるだけ

既存の「メールアドレスとパスワード」の会員と紐づけたいときは、ログイン中の会員が「Google と連携」ボタンを押したときに sub を保存する形にします。メールアドレスが同じというだけで自動で結びつけると、メールの確認状態によっては、別人のアカウントに入れてしまうおそれがあります。

ログアウト

/logout に POST すると、アプリのセッションが消えます。CSRF 対策が有効なので、GET のリンクではなく、上の Thymeleaf のようにフォームで送ります(Thymeleaf の th:action は CSRF トークンを自動で入れます)。

ログアウトの範囲 方法 Google で
アプリだけ /logout に POST できる。Google にはログインしたまま
ID プロバイダー(IdP)も一緒に OidcClientInitiatedLogoutSuccessHandler Google の Discovery ドキュメントに end_session_endpoint が無いので、この形にはならない
アプリの連携そのものを解除 https://oauth2.googleapis.com/revoke にトークンを POST できる(同意を取り消す)

Spring Security 7.1.1 のソースでは、OidcClientInitiatedLogoutSuccessHandler は、プロバイダーの設定に end_session_endpoint があるときだけ、そこへ移します。無いときは、ふつうの logoutSuccessUrl へ戻ります。Google の場合、アプリのログアウト後に「Google でログイン」を押すと、Google 側はまだログインしているので、すぐ戻ってきます。別のアカウントに切り替えたい人のために、上のコードでは prompt=select_account を付けています。 Google のドキュメントでは、prompt の値は none・consent・select_account です。

Keycloak など end_session_endpoint を持つ IdP では、IdP のログアウトまで行えます。関連記事「Keycloak入門|OIDCログインとJWT検証を最短で構築」で扱っています。

よくあるエラー

Google の画面に出るエラー

Google のドキュメント(ウェブサーバー アプリケーション向け OAuth 2.0)に載っているエラーです。

エラー 意味 直し方
redirect_uri_mismatch 認可リクエストの redirect_uri が、クライアント ID に登録した URI と一致しない 下の「redirect_uri_mismatch の原因」
invalid_client クライアント シークレットが正しくない ID とシークレットの組を確かめる
deleted_client クライアントが削除された(使われていないため自動で削除されることもある) 30日以内なら復元できる。無理なら作り直す
org_internal プロジェクトが特定の組織のアカウントだけに限られている 対象を「外部」にするか、組織のアカウントで入る
admin_policy_enforced Google Workspace の管理者のポリシーでスコープが止められている 管理者にクライアント ID を許可してもらう
disallowed_useragent アプリ内ブラウザ(WebView)から開いた 端末の標準ブラウザで開く
invalid_request リクエストの形が正しくない・必要なパラメータが無い scope・response_type などの設定を確かめる

redirect_uri_mismatch の原因

送られた URI 登録した URI 原因
http://app.example.com/login/oauth2/code/google https://app.example.com/… プロキシの後ろで、アプリが自分を http だと思っている
http://127.0.0.1:8080/… http://localhost:8080/… ホスト名の違い
http://localhost:8081/… http://localhost:8080/… ポートの違い
…/login/oauth2/code/google-login …/login/oauth2/code/google registration の名前を変えた
https://example.com/myapp/login/… https://example.com/login/… コンテキストパスの付け忘れ
…/google/ …/google 末尾のスラッシュ

いちばん多いのは1行目です。リダイレクト URI の {baseUrl} は、アプリが受け取ったリクエストから組み立てられます。nginx やロードバランサーで https を終端していると、アプリには http で届くので、http://… が Google に送られます。server.forward-headers-strategy: native(Tomcat などの組み込みサーバーで X-Forwarded-Proto を読む)か framework を設定し、プロキシ側で X-Forwarded-Proto と X-Forwarded-Host を渡します。どうしても合わないときは、redirect-uri に固定の URI を書く方法もあります。

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            redirect-uri: "https://app.example.com/login/oauth2/code/{registrationId}"

Spring 側のエラー(ログ・failureHandler で見えるもの)

Spring Security 7.1.1 のソースにあるエラーコードです。OAuth2Error の toString() は [コード] 説明 の形なので、DEBUG ログにはこの形で出ます。

エラーコード 出る場面 よくある原因
authorization_request_not_found Google から戻ったとき、保存しておいた認可リクエストがセッションに無い 行きと帰りでホスト名が違う(localhost と 127.0.0.1)、複数台でセッションを共有していない、戻るのに時間がかかりセッションが切れた
invalid_state_parameter 戻ってきた state が保存した値と違う ログインのタブを2つ開いた、前に開いたタブで戻った
invalid_token_response code をトークンに交換するのに失敗した シークレットの誤り(Google の invalid_client)、サーバーから Google へ出られない(プロキシ・ファイアウォール)
invalid_id_token ID トークンの中身が正しくない サーバーの時計のずれ(exp・iat)、client-id の誤り(aud)
invalid_nonce ID トークンの nonce が違う 同上(同時に複数のログイン)
client_registration_not_found /login/oauth2/code/xxx の xxx が設定に無い URL と registration の名前の不一致
invalid_request 戻ってきた URL に code も error も無い 戻り先の URL を直接開いた
access_denied(Google から) 利用者が同意を拒否した —

invalid_token_response の説明文は、ソースでは An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: の後ろに、通信の例外のメッセージを付けた形です。後ろの部分に Google の応答(invalid_client など)や Connection refused が入るので、そこで原因を分けます。

起動時のエラー(Spring Boot 4.1.1 のソース)

メッセージ 原因
Client id of registration 'google' must not be empty. client-id が空(環境変数が渡っていない)
Provider ID must be specified for client registration 'google-login' registration の名前が google 以外で、provider: が無い
Unknown provider ID 'gogle' provider: の綴りの誤り

よくある質問

Q. OAuth2User と OidcUser のどちらで受け取りますか。 A. スコープに openid が入っていれば OidcUser です。Google の既定のスコープには openid が入っています。GitHub のように OpenID Connect でないプロバイダーと共通で扱うなら、親の型の OAuth2User で受け取り、getAttribute("…") で項目を読みます。

Q. ログインしたあとに Google の API(カレンダーなど)も呼びたいです。 A. scope に必要なスコープを足し、@RegisteredOAuth2AuthorizedClient("google") OAuth2AuthorizedClient client でアクセストークンを受け取ります。Google のドキュメントでは、利用者がいないときにも使うリフレッシュトークンは access_type=offline を付けたときに返されます。

Q. REST API(SPA のバックエンド)でも同じ形で使えますか。 A. この記事の形は、サーバーがセッションを持つ画面のアプリ向けです。SPA からトークンを付けて API を呼ぶ形なら、API 側は「リソースサーバー」として JWT を検証します。関連記事「Spring Security JWT認証の実装|Boot 4対応の設定コード全文」で扱っています。

Q. ログイン後に 403 になります。 A. 権限(ロール)が足りないか、CSRF トークンが無い POST です。原因の切り分けは、関連記事「Spring Securityで403になる原因|POSTだけ失敗する時」で扱っています。

まとめ

  • 依存は spring-boot-starter-security-oauth2-client(Boot 4)。registration を google にすると client-id と client-secret だけで動く
  • リダイレクト URI は {baseUrl}/login/oauth2/code/google。https・ホスト名・ポート・コンテキストパスまで一致させる
  • プロキシの後ろでは server.forward-headers-strategy を設定する
  • ユーザーは sub で見分ける。メールアドレスをキーにしない
  • DB との紐づけは OidcUserService を継承して、権限も DB から付ける
  • ログアウトはアプリのセッションだけ。Google には end_session_endpoint が無い
  • 既定のログイン画面は理由を出さないので、failureHandler でエラーコードを取り出す

参考・出典

確認日はいずれも 2026年10月13日です。

  • Spring Security Reference「Core Configuration(OAuth 2.0 Login)」:https://docs.spring.io/spring-security/reference/servlet/oauth2/login/core.html
  • Spring Security 7.1.1 ソース(CommonOAuth2Provider・OAuth2LoginAuthenticationFilter・OidcClientInitiatedLogoutSuccessHandler・DefaultLoginPageGeneratingFilter):https://github.com/spring-projects/spring-security/tree/7.1.1
  • Spring Boot v4.1.1 ソース(spring-boot-security-oauth2-client):https://github.com/spring-projects/spring-boot/tree/v4.1.1
  • Google for Developers「Using OAuth 2.0 for Web Server Applications」:https://developers.google.com/identity/protocols/oauth2/web-server
  • Google for Developers「OpenID Connect」:https://developers.google.com/identity/openid-connect/openid-connect

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Spring BootでGoogleログイン|OAuth2 Clientの完成コード」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?