株式会社クイックのWebサービス開発blog

HAPPYなサービスプランナー・エンジニア・デザイナーのブログです。

Laravel Sanctumを使って簡単にパーソナルアクセストークン作ってみよう

こんにちは、Czです。
最近急に朝寒くなりましたね。

パーソナルアクセストークン(PAT)とは

Githubとかで使用されているパスワードの代わりに使用するトークンです。
これを使うことでコマンドラインまたはAPIの認証をすることができます。

Laravel Sanctumとは

f:id:aimstogeek:20211021180613p:plain

Sanctumとは「聖域」という意味らしいです。
認証周りを提供してくれているので名前通りかもしれませんね。

Laravel Sanctumは以下の2つの複雑さを解消するために存在しています。

今回は「APIトークン」に焦点を当ててお伝えします。

なお、Laravel Sanctum は Laravel8 から標準で入っています。
もし7以前で使いたい場合は、以下のコマンドでインストールすれば行けるはずです。

composer require laravel/sanctum

準備

ではまっさらな状態から作っていきましょう。
Laravel Sail を使って環境を構築します。

curl -s "https://laravel.build/sanctum-sample" | bash
cd sanctum-sample
./vendor/bin/sail up

これで環境が立ち上がりました。
http://localhost にアクセスして動いているかどうか確認してみてください。

...

では続いてSanctumを使ってtokenを作っていきたいのですが、tokenを作るためにはログインできなければなりません。

ログイン機能を1から作ると今(午後5時)から始めると日が暮れてしまうので、Laravel Jetstream を使ってサクッと作っていきましょう。
ちなみにJetstreamを入れなくてもSanctumの恩恵は受けることができるので最後まで見て不要だなと思われた方はインストールしなくても大丈夫です。

Laravel Jetstream のインストール

以下のコマンドでJetstreamをインストールすることができます。

./vendor/bin/sail composer require laravel/jetstream
./vendor/bin/sail artisan jetstream:install inertia

install時に指定している「inertia」ですが、他にも「livewire」を指定することができます。
両者の違いとしてlivewireは「blade」、inertiaは「Vue」を使ってフロント側が構築されます。
私の所属するプロジェクトではVueを使っているので今回はinertiaを指定しています。

...

これで認証機能が使えるようになりました。

使ってみよう(Jetstream)

では早速 http://localhost/register へアクセスしてみましょう。

以下のように登録画面が表示されたはずです。

f:id:aimstogeek:20211021155041p:plain

入力して REGISTER ボタンを押して登録してみます。

f:id:aimstogeek:20211021153943p:plain

このようにダッシュボード画面が表示されたはずです。

ダッシュボードの右上のアカウント名をクリックしてみます。

「Profile」と「Log Out」の2つの項目がありますね。

f:id:aimstogeek:20211021154026p:plain

デフォルトではToken機能が有効になっていないので有効化する必要があります。

jetstream.phpを開き、Features::api()コメントアウトを外します。

config/jetstream.php

'features' => [
    // Features::termsAndPrivacyPolicy(),
    // Features::profilePhotos(),
    Features::api(),
    // Features::teams(['invitations' => true]),
    Features::accountDeletion(),
],

そうすると、先ほどのメニューに「Api Tokens」が追加されます。

f:id:aimstogeek:20211021154052p:plain

tokenを作ってみよう

メニューからApi Tokensを選択すると次の画面が表示されます。

f:id:aimstogeek:20211021154121p:plain

Nameに「readonly」を入れて、
readにのみチェックを入れて、
CREATE ボタンを押します。

f:id:aimstogeek:20211021154138p:plain

こんな感じでTokenが表示されたはずです。
このTokenは一度限りしか表示されないのでメモしておきましょう。

uScF3qsBW2duh4UoCzyIkkpKwzlEHrDs0mtc0G7B

このtokenを使ってAPI認証することがPATの役割となっています。

tokenを使ってみよう

api.phpを見てみます。

routes/api.php

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

middlewareで「auth:sanctum」ガードが指定されています。 このガードではAuthorizationヘッダのトークンを使ってリクエストの認証を行います。

では、以下のコマンドを実行してみましょう。

// curl -H "Authorization: Bearer <token>" http://localhost/api/user
curl -H "Authorization: Bearer uScF3qsBW2duh4UoCzyIkkpKwzlEHrDs0mtc0G7B" http://localhost/api/user
{"id":2,"name":"Cz","email":"cz-hogehoge-dummy@google.com","email_verified_at":null,"current_team_id":null,"profile_photo_path":null,"created_at":"2021-10-20T16:14:15.000000Z","updated_at":"2021-10-20T16:14:15.000000Z","profile_photo_url":"https:\/\/ui-avatars.com\/api\/?name=Cz&color=7F9CF5&background=EBF4FF"}

トークンを発行した時のユーザの情報が取れていれば成功です。

...

「ん〜動いたけど、Jetstreamがよしなにやってくれてるからどうやって使うかイメージ湧かない。 」 って方はこの先も読み進めることをお勧めします。

理解しよう

ここからはJetstreamとSanctumの処理を追っていきながら、どう使えばいいか理解を深めていきましょう。

Jetstreamで有効にしたAPI機能の中を見てみる

先ほど config/jetstream.php でFeatures::api()のコメントアウトを外しましたが、
それによってどうなるかを見てみます。

今回はinertiaでインストールしているので以下のファイルを確認します。

vendor/laravel/jetstream/routes/inertia.php

// API...
if (Jetstream::hasApiFeatures()) {
    Route::get('/user/api-tokens', [ApiTokenController::class, 'index'])->name('api-tokens.index');
    Route::post('/user/api-tokens', [ApiTokenController::class, 'store'])->name('api-tokens.store');
    Route::put('/user/api-tokens/{token}', [ApiTokenController::class, 'update'])->name('api-tokens.update');
    Route::delete('/user/api-tokens/{token}', [ApiTokenController::class, 'destroy'])->name('api-tokens.destroy');
}

このようにindex,store,update,destroyの4つの機能が使えるようになるみたいです。

tokenを生成処理はApiTokenController#store()を呼び出しているようなので中を確認してみます。

vendor/laravel/jetstream/src/Http/Controllers/Inertia/ApiTokenController.php

/**
 * Create a new API token.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\RedirectResponse
 */
public function store(Request $request)
{
    $request->validate([
        'name' => ['required', 'string', 'max:255'],
    ]);

    $token = $request->user()->createToken(
        $request->name,
        Jetstream::validPermissions($request->input('permissions', []))
    );

    return back()->with('flash', [
        'token' => explode('|', $token->plainTextToken, 2)[1],
    ]);
}

ログインしているユーザのcreateToken()を使ってトークンの生成が行われていることがわかります。

この機能はUserモデルがtraitで実装している「HasApiToken」で提供されているようです。

HasApiTokenのcreateToken()を見てみる

vendor/laravel/sanctum/src/HasApiTokens.php

/**
 * Create a new personal access token for the user.
 *
 * @param  string  $name
 * @param  array  $abilities
 * @return \Laravel\Sanctum\NewAccessToken
 */
public function createToken(string $name, array $abilities = ['*'])
{
    $token = $this->tokens()->create([
        'name' => $name,
        'token' => hash('sha256', $plainTextToken = Str::random(40)),
        'abilities' => $abilities,
    ]);

    return new NewAccessToken($token, $token->getKey().'|'.$plainTextToken);
}

これを見るとplainTextTokenはStr::random()で生成されており、それをsha256でハッシュ化したものをtokenとして保存しているようですね。
(保存する際にkeyを|で結合しちゃっているのが気になりますが...)

さらに見ていくと、 戻り値はNewAccessTokenというクラスで、
accessTokenとして保存されるクラスはPersonalAccessTokenだということがわかります。

vendor/laravel/sanctum/src/NewAccessToken.php

/**
 * Create a new access token result.
 *
 * @param  \Laravel\Sanctum\PersonalAccessToken  $accessToken
 * @param  string  $plainTextToken
 * @return void
 */
public function __construct(PersonalAccessToken $accessToken, string $plainTextToken)
{
    $this->accessToken = $accessToken;
    $this->plainTextToken = $plainTextToken;
}

PersonalAccessTokenを見るとEloquenモデルを継承しているのでDBで管理していることがわかりますね。

use Illuminate\Database\Eloquent\Model;
use Laravel\Sanctum\Contracts\HasAbilities;

class PersonalAccessToken extends Model implements HasAbilities

対応するpersonal_access_tokenテーブルを確認してみましょう。

personal_access_tokenテーブルを見てみる

Laravel sailではdocker-composeの機能を内包しているので、以下のコマンドでdockerで立ち上がっているmysqlサーバにアクセスすることができます。

./vendor/bin/sail mysql

personal_access_tokenテーブルが存在するsanctum_samleのDBに切り替えます。

mysql> use sanctum_sample;
Database changed
mysql> show tables;
+--------------------------+
| Tables_in_sanctum_sample |
+--------------------------+
| failed_jobs              |
| migrations               |
| password_resets          |
| personal_access_tokens   |
| sessions                 |
| users                    |
+--------------------------+

そして登録されているtoken情報を確認してみます。

mysql> select * from personal_access_tokens\G;
*************************** 1. row ***************************
            id: 1
tokenable_type: App\Models\User
  tokenable_id: 1
          name: readonly
         token: 2dbe71b931d2f008c9e3555cce089b399d66b99e39acbf31b059bb63f25be3c3
     abilities: ["read"]
  last_used_at: NULL
    created_at: 2021-10-18 15:18:04
    updated_at: 2021-10-18 15:20:17
1 rows in set (0.01 sec)

先ほど作成したtokenがありましたね。 read権限はabilitiesカラムの中におり、json形式で複数設定できるようにしているみたいですね。

保存先が「personal_access_tokens」ということがわかったところで一旦戻ります

plainTextTokenの返却部分を見てみる

再度ApiTokenController#store()を見てみましょう

vendor/laravel/jetstream/src/Http/Controllers/Inertia/ApiTokenController.php

/**
 * Create a new API token.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\RedirectResponse
 */
public function store(Request $request)
{
    $request->validate([
        'name' => ['required', 'string', 'max:255'],
    ]);

    $token = $request->user()->createToken(
        $request->name,
        Jetstream::validPermissions($request->input('permissions', []))
    );

    return back()->with('flash', [
        'token' => explode('|', $token->plainTextToken, 2)[1],
    ]);
}

前の画面にリダイレクトする際にflash messageとしてplainTextTokenを返しています。 これでユーザにtokenを渡しているということですね。
なおplainTextTokenはこのように($token->getKey().'|'.$plainTextToken)keyが結合されているので、わざわざ|で分割して純粋なtokenのみを抽出しています。
(explodeの第3引数でlimit=2を指定しているところは丁寧だなぁと思いました)

ここまでがSanctumとJetstreamで行っているtoken生成の流れでした。

最小構成で作ってみよう

Jetstreamのコードを追っていって作り方が分かったと思うので最小構成で作ってみましょう。

tokenの作成

supermanというabilityを持つtokenを生成するロジックです。
以下のコードをweb.phpに追記します。(たったこれだけ)

routes/web.php

Route::middleware(['auth:sanctum', 'verified'])->get('/token/create/{name}', function (Request $request) {
    $token = $request->user()->createToken(
        $request->name,
        ['superman']
    );
    return explode('|', $token->plainTextToken, 2)[1];
})

/token/create/<任意のtoken名>にアクセスするとplainTextTokenが画面に表示されるはずです。
とりあえずこのtokenは控えておきます。

DBにレコードが追加されているか確認してみましょう。

mysql> select * from personal_access_tokens order by id desc limit 1\G;
*************************** 1. row ***************************
            id: 4
tokenable_type: App\Models\User
  tokenable_id: 1
          name: hoge
         token: 54c8de8c2b2346ece1c4d6257c0c23e40b02681c220eb96c04f2611a590a1bbd
     abilities: ["superman"]
  last_used_at: NULL
    created_at: 2021-10-21 03:38:42
    updated_at: 2021-10-21 03:38:42
1 row in set (0.00 sec)

ちゃんと追加されていましたね。

tokenの使用

続いてAPIを作成しましょう。

supermanアビリティを持つユーザでアクセスすると「You are Superman!!」を
持っていない場合は「You are NOT Superman.」を返します。

以下のコードをapi.phpに追記します。(たったこれだけ)

routes/api.php

Route::middleware('auth:sanctum')->get('/superman', function (Request $request) {
    return response()->json([
        'message' => $request->user()->tokenCan('superman')
            ? 'You are Superman!!'
            : 'You are NOT Superman.',
    ]);
})

そして実行...

# supermanアビリティを持つtokenでアクセス
curl -H "Authorization: Bearer VWWjM8k09fwIayViFaVIBCod0e4GrJIGqoOwCBPy" http://localhost/api/superman
{"message":"You are Superman!!"}

# supermanアビリティを持たないtokenでアクセス
curl -H "Authorization: Bearer uScF3qsBW2duh4UoCzyIkkpKwzlEHrDs0mtc0G7B" http://localhost/api/superman
{"message":"You are NOT Superman."}

# 正しくないtokenでアクセス
curl -H "Authorization: Bearer VWWjM8k09fwIayViFaVIBCod0e4GrJIGqillegal" http://localhost/api/superman
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url='http://localhost/login'" />

        <title>Redirecting to http://localhost/login</title>
    </head>
    <body>
        Redirecting to <a href="http://localhost/login">http://localhost/login</a>.
    </body>
</html>

tokenが正しくない時にlogin画面へ行っちゃいましたが、tokenが正しい時はアビリティによって振る舞いを変えることができましたね。

最後に

と、まぁこんな感じで簡単にパーソナルアクセストークンを使うことができました。
パーソナルアークセストークンを使えばブラウザを介さずとも操作できるので、社内ツールの拡張機能として使うのもアリかもですね!

下の方が余ったのでコロナ禍で迎え入れたうちのうーちゃんを紹介します。
サバトラ白/♀)

f:id:aimstogeek:20211021154332j:plain
uh-chan
ほんと毎日癒されています。



\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! //

919.jp

AWS Step Functionsでワークフローを視覚化する

こんにちは。ソフトウェアエンジニアのやぎーです。

最近ノーコード・ローコード開発について耳にすることが多くなったので、 AWSのStep Functionsを紹介させていただきます。

ノーコード・ローコード開発とは

ノーコード開発

ソースコードの記述を全く行わずにアプリケーション開発をすること。
プログラミングの知識なくても開発できますが、できることが限られていたりします。

ローコード開発

少ないプログラムコードでアプリケーション開発をすること。
プログラミングの知識は必要ですが、拡張性や柔軟性があります。

AWS Step Functionsとは

AWSのリソースの連携、自動化のワークフローの作成や実行ができるサービスです。 SQSやLambdaで実行したいサーバーレス処理のワークフローなども Workflow Studioを使ってGUIから簡単に連携させることができます。

Step Functionsはローコード開発ツールになります。

フローイメージ

今回は下記のような簡単なフローを作成しようと思います。

  1. SQSメッセージを起点にフローを開始する
  2. 特定のファイルに対して処理を実行する
  3. 変換が成功した場合、ファイル情報を保存する
  4. 実行結果を通知する

それではStep Functionsを設定していきます。

ステートマシンの作成

まずはStep Functionsからステートマシンを作成します。

「ステートマシンの作成」をクリック f:id:aimstogeek:20211006153029p:plain

「作成方法」は、Workflow Studioを使ってGUI上で作成したり、
ASL(Amazon States Language)での作成もできますので、お好みに合わせて選択してください。 f:id:aimstogeek:20211006153035p:plain 今回はWorkflow Studioを使ってワークフローを作成していきます。

ワークフローの作成

作成したステートマシンに、ワークフローを設定します。

左側にAWSのリソースやフローが表示されるので、右側にドラッグドロップすることでフローを作成できます。 f:id:aimstogeek:20211006153128p:plain

下記が実際に作成したワークフローになります。 f:id:aimstogeek:20211006153155p:plain ファイル変換処理の結果がSNS経由で送信されます。

ロジック自体はLambdaなどで作成する必要がありますが、 処理の流れや役割がイメージしやすくなるのではないかと思います。

メリット

  • プログラムを読まなくても処理の流れがイメージできる
  • 処理の分岐や並列化などもWorkflow Studio上で簡単に設定できる
  • AWSリソースとの連携が簡単

デメリット

  • 実行速度はあまり早くない
  • AWSサービスの知識は必要
  • CloudFormationの記述は多くなる

最後に

ローコード・ノーコード開発が普及することで、開発生産性の向上や、 システムの管理・保守が容易となり、DXの推進にもつながるのではないかと思います。

使い方によっては既存の開発コストを減らしたり、品質の向上に繋がると思いますので、 見直すきっかけとなれば幸いです。

最後までお読みいただきありがとうございました。



\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! //

919.jp

「フォックス君」の誕生に至るまで

f:id:aimstogeek:20210930202939j:plain こんにちは。デザイナーのタニモです。
Withコロナの生活が続く中、皆さんは如何お過ごしでしょうか。今回は私が最近デザインを手掛けた お仕事の1つをご紹介しようと思います。
この度、弊社が運営するサイト「転職Hacks」において、特集「履歴書の書き方」「職務経歴書の書き方」 「面接ガイド」に登場するマスコットキャラクターをデザインさせて頂きました。 今回はこのキャラクターのご紹介と制作過程のお話です。弊社のイラストレーター業務、デザイナー業務に 興味をお持ちの方に、少しでもお役に立てて頂ければ幸いです。

フォックス君

デザインしたキャラクターはコチラ!
「転職Hacks」のフォックス君(正式名称:フォックス・ネイビー)です!
ネーミングはプロジェクトメンバーと検討を重ねたのですが、一周回って無難な「フォックス(キツネ)」に落ち着きました。(笑)
f:id:aimstogeek:20210930204831p:plain

キャラを作ることになった経緯

「転職Hacks」は転職活動に役立つ情報をまとめた記事サイトです。情報の網羅性や誠実さを強みとしていますが、 一方で内容が難しそう、ハードルが高く見える、といった課題も抱えていました。新たな特集ページのプロジェクトに 参画した際、もう少し親しみやすいサイトを目指すための 1つの策として、マスコットキャラクターを作ってみてはどうか?と提案させて頂いたことがきっかけで、 そのデザインを担当することになりました。

制作過程

ここからは、キャラクターのデザインが完成するまでの制作過程と簡単なノウハウについてご紹介します。

ステップ① キャラの存在意義を考える

キャラクターを制作する際、まず最初に行うことは、上述したようなサイトのコンセプト、ビジョン、課題などを しっかりと把握することです。これらを理解した上でキャラクターの使用目的を考え、存在意義を明確に示します。 今回は「ユーザーに寄り添い、親しみやすく、転職活動の不安を取り除いてあげられるような 存在」が求められたため、それに相応しいキャラクターのビジュアルを検討しました。

ステップ② キャラのビジュアル設定を考える

キャラクターのビジュアル設定は、描く前にまずテキストレベルで検討します。 頭身やモデルとなる生き物など、ビジュアルを構成する要素のアイデアはなるべく幅広く検討し、 あらゆる可能性を探った上で、最も相応しい要素を選択してまとめていくと良いでしょう。 今回の使用目的を考慮し、モデルは「2〜3等身の動物」が望ましいと判断しました。

次に動物の選定です。「転職」がテーマのサイトなので、それにちなんだ動物が良いです。 …そう言われてもピンときませんね。(笑)
発想を広げるために、「転職」を別の言葉に置き換えていきます。 「職を変える」「自分を変える」「姿を変える」「変身」など。「変身」で連想する生き物は、 カメレオン、昆虫、擬態する生き物などがありますが、いずれも親しみのあるキャラとしては魅力に欠けそうです…。 ここで「変身」を「へんげの術」としたところ、御伽噺のキツネとタヌキが候補に上がりました。 どちらも馴染みのある動物で、キャラとしての魅力も引き出せそうです。 最終的に、以下の理由でキツネに決定となりました。
 ・Hacks(ハックス)とフォックスで発音が似ているので覚えやすい
 ・キツネは賢いという印象から、ビジネスやスーツ姿が合いそう
 ・「転職Hack」のキーカラーのオレンジがキツネの色と相性が良い
 ・「転職Hack」のキーカラーの紺(ネイビー)とキツネの鳴き声「コン」

ステップ③ ビジュアル作成

ここまで設定を固めた上で、ビジュアルのラフ案作成に入ります。 今回はマスコットキャラクターとしての可愛らしさや親しみやすさを出しつつも、「信頼」「網羅性」「誠実」といった 「転職Hacks」が持つ強みも感じられるビジュアルを検討しました。 アウトラインはパキッとした一定の太さで手描き感を抑え、塗りは「転職Hacks」のキーカラーを使ったシンプルな単色塗りに。 顔つきは博識で余裕のある表情にし、体はスーツの装い。フォーマルで公式感を感じられるデザインに仕上げました。 額に載せた木の葉は変身(=転職)する時に使うアイテムという設定。チャームポイントは、大きな耳と尻尾です♪
ちなみに、制作途中のラフ案はこんな感じでした。

f:id:aimstogeek:20211001195855p:plain

以上がフォックス君誕生に至るまでの経緯です。いかがでしたでしょうか。
クイックに中途入社して間もない私に、今回このような楽しいデザイン業務を担当させて頂けたことを 心から感謝しています。今後も自身のスキル・強みを生かし、成果に繋げていければと思っています。

最後までお読み頂きありがとうございました。
イラストやデザインの力で私たちと一緒にクイックの事業発展・拡大に貢献してくれる方、 いつでもお待ちしております!


\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! //

919.jp

会社でGoogle ClassRoomを使い始めた話

こんにちは、ソフトウェアエンジニアのiwateaです。

最近会話の話題が健康に関するものが増えて、あっ大人になるってこういう事か...としみじみ実感する今日このごろです。
しかし、いつまでも若い気持ちは持っていたいという事で、今回は学生時代を思い出すようなサービスの話でいきたいと思います。

ということで、今回はGoogle Classroomをある業務で導入した話です。

えっ、Classroomって学校??と思われたあなた、その通り。
そんな学校向けのサービスを会社で使ってみたという話です。

導入前に起きていたこと

システム開発の現場では外部のエンジニアに常駐して頂く事が多いのですが、受け入れの際に経歴書の書類審査を行っています。

ですがこの書類審査、観点の明文化が中々難しく「明日から君も審査よろしく!」と言われても、「え、どういう観点で見ればいいんだろう??」となってしまいます。

この問題を解決するための取り組みとして、これまで採用をやっていた人 + これから担当してもらう人に同じ経歴書を見てもらい、合否とその理由を明文化してノウハウを共有していく運用を試しに行ってみることになりました。

お試しの取り組みというのもあり、会社全体で使ってる採用管理サービスを使ったり、新しく有料サービスを契約しようという温度感では無かったため、最初はチャット上でやり取りを行っていましたが、運用を続けていると以下の問題が早々に発生しました。

  • 誰がどの人の審査まで終わってるか分かりにくい
  • 数が多いと、これ誰のだっけ?となる
  • 無意識に他の人の判断に引っ張られてしまう
  • 実際面談した後のフィードバックを受けても、どの人だっけ…?となる

Google Classroom導入までの動き

問題は薄々感じている中、ある日Google Classroomの記事を見て会社でも使えそうだなーと思って雑談部屋で発言したら導入されてました。

f:id:aimstogeek:20210915160146p:plain

この間30分である。

Google Classroomとは?

edu.google.com

Google Classroomで出来ることは元々シンプルですが、会社で使う事を想定すると更に以下の機能の部分に絞って使えそうです。

  • 課題や質問を作成してメンバーに依頼する
  • 誰が回答したかの管理ができる
  • 選択したメンバーにメールで連絡できる

例えば前述した採用ノウハウの件では下記の使い方をしています。

  1. エージェントから来た経歴書や情報を質問として登録
  2. 担当者が各自チェックし、書類での合否や理由をコメントとして提出
  3. 提出すると他の人の回答が見れるようになるので自分の観点との違いを理解する
  4. 提出されたコメントは面談時に活用する
  5. 面談結果のフィードバックをコメントして終了

この運用にしてからは、特に同時に書類が来た時の対応が楽になりました。

使ってみてどうだった?

あくまで代替手段ではあるので特定の業務に特化したサービスには及びませんが、組織につきものの雑務を改善する取り組みを「とりあえずやってみよう!」という時に使えるシーンは多いと思いました。

例えばメンバー全員に書類を提出してほしい時に誰が提出済みなのか管理が楽になるので、チームや部署の単位で作ってみるのも良いのではないでしょうか。

最後に

採用と言えば大企業は転職回数が多い人は敬遠されがちなイメージがありますが、かくいう私も35歳で6社目ですが元気にやっております。

弊社のメンバーにはゲーム好きな人からピッツァに異様なこだわりのある人、コンビニアイスを探し求める戦士たちなど色々な人たちが所属していますので、自分はちょっと変わってるから合わないかも...と遠慮がちなあなたの応募を是非お待ちしております!


\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! //

919.jp

デザインを「みんなのもの」として考えてみたらどうでしょう

デザインを「みんなのもの」

こんにちは。デザイナーの佐藤 宜也(ヨシナリ)です。

デザイナーの仕事のスタンスとして、デザインを「誰のため」と考えると「ユーザーのため」となります。
では、その「ユーザーのため」のデザインは「誰のもの」なのでしょうか。

普段、僕は自分のデザインに責任を持つ意味で「デザイナーのもの」という思いで魂こめてデザインをしています。
ただ、その考えを持ちつつも、「みんなのもの」という考えもアリかなとも思うようになってきました。

なぜなら、サービスデザインをしていると、たくさんのメンバーのアイデアを重ねたうえで、ひとつのデザインに到達することが多いですし、プロジェクトメンバーみんなで、デザインを「みんなのもの」として見られるようになると、メンバー間の合意形成はもちろん、そのデザインを自分のものとして愛してもらえるようになるんじゃないかと思ったからです。

真の一枚岩のチームとなり「ユーザーのため」の最高のサービスの実現に近づけるために。
そのためにも、デザインを「みんなのもの」と思ってもらえるようにしていきたいなと考えるようになってきました。
その実現のためにプロジェクトチーム内でやってきたことをいくつか紹介させてください。

やってきたことを整理してみると、3つに分類できました。
まずは【目的】の共通認識。ゴールがバラバラだと、みんなで話すことはできません。
そして、それを実現するための【制約条件】を定義すること。自由すぎるノールール状態は、アイデアを集約しづらくなり、誰かの大きな一声に一蹴されてしまいがちです。
最後に【具体化】するための体制です。ここがブレると、カタチにできません。

前置きが長くなりました。順に説明させてください。

【目的】ユーザー像を共通認識にする

僕らの目的は「ユーザーのため」です。
その実現のため、メンバー内の「ユーザーの解像度」をはっきり具体化していこうと考えました。
元々、しっかりとした土台はあったので、UXツールを用いて、さらに具体性を上げて堅牢にしていこうと試みました。

そのためのツールとして「ペルソナの再定義」「ユーザビリティテスト」「デプスインタビュー」「価値マップの制作」を実行しました。 これらひとつひとつの説明は、ここでは割愛します。セオリーに忠実に基づき実行しました。
ここでは、ツールを実行するにあたって、僕なりに強く意識した3点を伝えさせてください。

1:なるべく同じメンバーに関わってもらう

それぞれのツールによる結果が独立したままにならないように、1人の人間の中でそれらが関連してひとつの思考になってほしいと考えました。
関わったメンバーの脳内で、その情報が点から線に、そして面になることで、ユーザー像がリアルに見えてくることを狙いました。
特に、サービス内施策の意思決定に大きく関わるリードプランナーと、デザインを具体化するデザイナーには、深く関わってもらいました。
めちゃ忙しい中、ありがとう。ありがとう。

2:結果をチーム内で日常的に啓蒙し続けていく

もちろん、関わっていないメンバーへの共有も大事です。むしろ、こっちの方が重要度は高いかもしれません。
ここをしっかりやらないと、手間ヒマかけてツールを実行した意味が無くなってしまいます。
大切なのは、日常的に啓蒙し続けていくこと。
一回の広報でみんなの意識に定着させることは難しいと思うからです。
反芻することで、メンバー内でのユーザー像が定着し、ユーザー像ありきで議論を進めことができると考えています。
そのために、常にペルソナの資料を見る習慣をつけたり、インタビューエピソードを根気強く言語化することを心がけています。

3:できるだけ早く施策に反映させる

試行は鮮度が命です。可能な限り早く具体的に使用することで、その精度に磨きをかけられるかと思います。
例えば、インタビューで聞いた話を数時間後のMTGにすぐに活かして、クリエイティブに反映させたり。
一気通貫な僕らの体制だからこそ、そのスピード感を実現できました。
また、その情報が「使える道具」として認識できることで、その情報の価値を実感できることも期待されます。

まとめ:ユーザー像を判断材料として考える

UXツールにより導き出されたユーザー像がプロジェクトで活用されるよう、上記3点を強く意識してきました。
その結果、ユーザー像が具体化され、その意思決定の判断材料として明確に活用されてきていると感じています。
この状態だからこそ、メンバーみんなで公平に議論ができるようになり、そこから生み出されるデザインは「みんなのもの」になるのではと考えています。

ユーザー像がメンバー内でさらに定着し共通認識になる状態を目指して、現在も遂行中です。

【制約条件】デザインシステムの活用

デザインシステムは、今やサービスデザインになくてはならないものになっているかと思います。
メンバーの共通認識、属人性に頼らないクオリティ担保、デザインの一貫性などなど、その価値は数多くあります。
それらの価値を活かすためにも、実務の中で活用していくことが重要です。

そして、活用することでデザインシステムありきでデザインを語る事となり、その結果、メンバー内にそのルールが定着していきます。
そのルールに基づくことで、そのデザインがアリかナシかを誰もが公平に議論できる状態になると思います。

デザインのあるべき姿のひとつは、「制約の中での表現の最大化」にあります。
だからこそ、「みんな」でデザインを考えるためには「みんなのルール」が必要です。
そのルールを見える化しているという点が、「デザインシステム」の重要な機能のひとつだと考えています。

【具体化】フロントエンドエンジニアとしっかりタッグを組む

この体制は、常々Webデザイナーとしてマストだと思っていたので、実現できて嬉しく感じています。
Webデザインは実装されることで初めて完成となるのですから。
その実現のために必要なのは、デザイナーとフロントエンドとの共創体制なんじゃないかなと思います。

そもそも職能としてフルスタックな人が求められますし、デザイナーとフロントエンドは二人三脚。戦隊ロボットのごとく合体することで最大の成果を出せると思っています。
そんな思いも込めて、デザイナーとフロントエンドエンジニアとのチームとして「フロントチーム」と命名しました。

定期MTGを通して、お互いの思想や重要と考えていることをフラットに意見交換し、お互いの知見を活かすことで、最適なフロントを一緒に制作していくチームを目指しています。
同じ目線で議論を重ねることで課題感も同じになるので、共創感をもって一緒に制作を進められているんじゃないかなと感じています。

この体制でやれることはまだまだたくさんあると思っていて、今よりもっと生産性の高い制作体制を実現できるとワクワクしています。

一緒にデザインしませんか

いかがでしたでしょうか。
今、継続中のものも含めて、つらつらと書かせていただきました。
いろいろと書きましたが、日頃からデザインを「みんなのもの」という意識をもってメンバーと接することが、何よりも大事だと思っています。
日々の小さな積み重ねが大きな成果につながるんじゃないかと。
「小さなことを積み重ねることが、とんでもないところに行く、ただひとつの道だと思う」
イチローの言葉です。

「ユーザーのため」に「みんな」のデザインを一緒にデザインしませんか?
少しでも共感してくれたら嬉しいです。気軽に連絡ください(^^)

読んでいただきありがとうございました。


\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! //

919.jp

楽しく!円滑に!仕事を進めるため、プロジェクトでやっていること

こんにちは!
最近仕事が楽しい!!!!そんなちーかまです。

どうしてこんなに仕事楽しいんだろう?と考えたときに

  • 仕事に慣れて色んなことができるようになってきた
  • 不明点や問題点を相談しやすい環境が整っていて安心感がある
  • 開発フローの改善により仕事が進めやすい
  • プロジェクトメンバーの人柄や考えていることがわかってきた

ことが理由として挙げられるなと思いました。
仕事に慣れて色んなことができるようになってきたから、に関しては駆け出しエンジニアだった私の軌跡をまとめたことがあったので置いておいて...

(ちなみに過去記事はこちら!) aimstogeek.hatenablog.com

今回は

  • わからないことや問題を相談しやすい環境を整える
  • 開発フローを改善して仕事を進めやすくする
  • プロジェクトメンバーの人柄や考えていることを理解する

ために、今所属しているプロジェクトがどんなことをしているかについて紹介していきたいと思います!

デイリースタンドアップの実施

毎日30分、進捗や勤怠の報告をするためにミーティングを行っています。
ファシリテーターは日替わりでメンバーが担当しており、流れは下記の通りです。

  1. 勤怠などの全体連絡を行う
  2. ガントチャートを画面共有しながら、各タスクの担当者が進捗や障害報告
  3. 余った時間でミニゲーム

このミーティングにはさまざまなメリットがあります。

  • ファシリテーターが交代制であるため、主体性を持って参加する気持ちが芽生える
  • 誰が今なにをやっているのか、遅れが出ているのか巻いているのかがわかる
  • タスクを進行する中で困り事があったときに、毎日相談する機会がある
  • ミニゲームを通じてメンバーの人柄がわかる

個人的にミニゲームが気に入っていて、タスク上あまり関わる機会のないメンバーの人柄を知るのに役に立っています!
ちなみに今日はワードウルフという、みんなであるお題について制限時間内に雑談をしてその雑談の中で「みんなとは違うお題」を与えられた少数派の人を見つけ出すゲームをしました。
みんなのお題公表後「水族館定番じゃないの?!」「めっちゃ新一の水族館デート覚えてるじゃん...」等また新たにメンバーに関する知識が増えた回でした。

f:id:aimstogeek:20210902170042p:plain

誰でも、いつでも利用できるビデオ会議の部屋作成

通称「だべりば」と呼ばれる、部屋立てをせずともURLにアクセスするだけでビデオ会議が始められる部屋を用意しています。
なので会話を始めるための準備はとても簡単!チャットで話したい相手をだべりばに呼び出して、URLにアクセスして終わりです。

f:id:aimstogeek:20210903080935p:plain

当初は「テレワークになってから気軽にメンバーと話せる機会がなくなった、自由にお話したい!」という目的でひとまず一部屋作成したのですが、

  • 有識者に相談したい
  • レビューコメントを補足するのに、口頭で伝えたい
  • 画面共有して作業のダブルチェックしてもらいたい

等々あまりの需要の多さになんと今では4部屋用意しています!!
実際自ら部屋を立ててURLを共有する必要性がなくなるだけで、準備の煩わしさが減るし時間削減にもなります。
「ちょっと話したいけどミーティングするほどでもない...」というときにとても便利で、気軽に相談しやすい環境づくりに繋がっています。

振り返りの実施

基本毎週1時間振り返りを実施しています。
こちらもファシリテーターは週替わりでメンバーが担当しており、話す内容は下記の4項目です。

  1. KPT(前回のKEEPとTRYも振り返る)
  2. その他感想
  3. 感謝の気持ち
  4. 個人の反省

f:id:aimstogeek:20210903081504p:plain

この振り返りがチームに与えている影響は非常に大きく

  • ファシリテーターが交代制であるため、主体性を持って参加する気持ちが芽生える
  • 人のしたミスを共有することで別の人による再発防止になる
  • 現環境が最適なのか、問題や解決する方法はないか、を考えることにより開発フローがどんどん改善されていく
  • プロジェクトに対して思っていることを共有するハードルを下げることができる

と、実際にどんな効果があったかをまとめるだけで記事もうひとつ書けちゃうくらいです...!
振り返りを始めてから1年半以上経ちますが、今も我がプロジェクトはよりよいフローで開発できるよう、そしてより質の高いアウトプットを行えるよう精進しています!!

最後に

以上が

  • わからないことや問題を相談しやすい環境を整える
  • 開発フローを改善して仕事を進めやすくする
  • プロジェクトメンバーの人柄や考えていることを理解する

ため、プロジェクトでやっていることでした。
みなさんの参考になっていたら幸いです!





\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! // 919.jp

【アイデアのヒント】現役イラストレーターが日々チェックしているサイトTOP3

こんにちは、イラストレーターのネモトマです。

会社では沢山のイラスト制作業務を行っていますが
アウトプットばかりに徹するとふとした拍子に
「も、もうネタがない・・・」
なんて糸が切れたような想いに駆られることがあります。

ネタというのは具体的に、

  • 案件にあった絵柄とはなにか

  • 世の中的に今何が流行っているのか

  • ユーザーに向けた適切な表現とは

  • 自身に足りてない技術は何か

  • そもそもアイデアが沸かない‥

といったようなことです。

とくに流行りなんてものはすぐに移り変わっていきますし、
その中に身を置いていないと気が付きようもないので
その場その場で調べるよりも日頃から感じておくのがよいな
という結論に至りました。

そこで、独断と偏見で選んだ

【アイデアのヒントを得るために現役イラストレーターが日々チェックしているサイトTOP3】

をご紹介します。

同業者で「他の人がどういったところで情報収集をしているか」が気になる方、
はたまた情報収集に使えそうなサイトがないかをお探しの方のお役に立てましたら幸いです。

今回は友人イラストレーター数名とも話して、意見がかぶっていたものを抜粋してみました。
それでは早速ご覧ください。


1位 TwitterInstagram

twitter.com about.instagram.com
誰もが使っているであろうSNS二大巨頭。
いわずもがなインプットとしてもとても優秀で、見ていない日はありません。

勉強になるアカウントはすべてリストに入れておいて毎日チェック
役に立つものは保存しておけば間違いありませんし
投稿を並べて見れば
「世の中の流行り」みたいなものも見えてきますので大変便利です。
自分が気になる情報がどんどこ手元に入ってくるっていいですね。

Twitterだと「トピック」という機能があるので、
気になるものをフォローしておけば
旬な情報が入ってくるので重宝しています。



2位 ピンタレスト: Pinterest

www.pinterest.jp
出会ったあの日から忘れたことがないピンタレストさん。
情報収集に便利すぎてこの子なしでは生きていけません。

自分のほしい情報を細かにピン(ブックマーク)することができることも便利ですが
なにが素晴らしいって、関連画像の的確さ。
かなり似たものから、やや関連まで細かに芋づる式に情報が得られるので
的確なキーワードが思いつかなくても欲しいイメージにたどり着ける優れもの。



3位 ArtStation・pixiv

www.artstation.com www.pixiv.net
こちら2つのサイトは双方ともにイラスト投稿サイトです。
ArtStationは海外のサイトで、兎に角ハイクオリティでクリエイティブの幅も広い印象。
pixivは日本のサイトで、プロアマ問わず気軽に投稿でき日本で流行っている絵柄だったり作風を感じやすい印象です。

表現や技術的な知識は他者の作品から得られることも多く
日頃のクリエイティブ制作にも繋がるので
毎日とは言わずともチェックするようにしています。
また、「良いものを作るためには良いものを見続けなければいけない」という信念があるので
嫉妬に狂いながらもしっかりチェックしています。


最後に

以上、個人的に抜粋させていただきました素敵サイトTOP3でした。
ド定番ではありますが、本当にお世話になっております。

今回は私が特にチェックしているものを挙げさせてもらいましたが、
他にもきっといいサイトが沢山あると思うのでぜひぜひ教えてください!





\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! // 919.jp