tekitoumemo’s diary

思ったことを書くだけ。長文版Twitter

ユーザー車検に向けて整備

3年前に購入した中古車の車検の季節がやってきました。

ユーザー車検は二回目ですが、前回はノー整備で余裕合格だったんで今回はある程度自分で整備します。

まず、オートバックスとかで見積もりを取る

車に詳しい人はここを端折っても良いのですがわからない人はある程度見てもらった方が良いでしょう。こんな感じでとりあえずいろんなものが見積もりに付けられます。

ここで気をつけて欲しいことをいくつか。
・オイル交換系(エレメント、フラッシング)
これは基本マメにやってる人が多いのでいらないっす。まず、車検でここはチェックされない。タイミングが合えばやればいい程度。フラッシングは一生やらなくていいと個人的には思ってる。
・エアコンフィルター
意味が分からない。オプションの車もあるので車検関係ない。自分で余裕で交換できる
ブレーキフルード
量あれば余裕。
・アンダーコーティング
意味不明。
・ブレーキパッド
多少あれば余裕で通るけど、足回りは交換しても良いかも。店舗だと純正品に交換させられて高いからモノタロウとかでちゃんとした社外品買ってつけても良いかも。
・ワイパー
たしか見てなかった気がする。ぶっちゃけ関係ないので気が向いたら交換程度でおけ
・タイロットエンドブーツとロアアームブーツ
ここで車検落ちる人が多いらしい。基本破れてなければオッケーで、ちょっとヤバくても受かると思う。モノタロウで300円程度だから交換しても良いかも。俺はヤバかった。

整備

僕がやった範囲で説明します。

違和感がないか

異音、エンジン掛けるとき、ブレーキ、アクセルらへんを確認。普通に走ってればだいたい大丈夫。

ウォッシャー液

イッチバン安いので良い。200円で買える。水より安い

オイル漏れ

ここは確認しづらいですが、駐車場などでエアコンかけずに5分ぐらいエンジンかけたまんまニュートラルにします。それで車を移動して、車のあった場所が濡れてないか確認。オイルっぽくなければおけ。

ブレーキパッド

テッチンだとタイヤ外さないと見えない。社外のホイールおススメ。これは目視で確認できる。MKカシヤマってのが信用出来るのかな?

タイロットエンド周り

先程貼った画像の箇所。ブーツが破れてグリス出てないか確認。この大野ゴム工業が割と信頼出来るのかな?ちなみにタイロットエンド自体交換しろと言ってくるところは無視。ロアアームはあまり劣化しないから基本大丈夫なはず。

タイヤ

社外ホイールの場合、このマーク確認。だいたい付いてるが。

注意

無理せず、業者にお願いしよう!特に中古車買った人は、前のオーナーがどんな整備してるか不明なので見てもらうこと大事!僕の場合、タイロットエンドにパッキンされてて意味わからないことになってました。持ち込みでやってくれるとこ結構あるので、好きな方法で換えましょう。

ユーザー車検のメリット

値段が安い。法的費用は車にもよりますが二桁万円は行きません。店舗だと法的費用の2.5倍かかるので圧倒的におトク。車の維持費はここが結構ネックなので自分である程度見れると良い車が乗れます。プリウスとかノートとか無駄に高い車でなくカッコいい車に乗れるようになるので今回も自分で行こうと決めました。あとボロ車に金掛けたくない人多いと思うので、有給取って行ってみるのも良いのではないでしょうか。割と楽しいです。

ちなみに

今年まだ受けてませんが、受かる気しかしないです。またブログ書きます。

2018年振り返って

2018年はいろんなことがあったので振り返ります。

自己満日記ですが一応自己紹介は以下の記事で。

仕事のこと

フリーランスになった

給料とか給料とか給料とかでフリーに転身した。流石に受注とか自分のサービスで生計立てられないから業務委託。今年はずっと同じとこにいたので「あれ?転職したのかな俺?」ってよくわからない状態。下手するとあと一年以上は延長されるっぽいので、早めに退散しようと思ってる。

webサービス作った


趣味の延長。月5000〜10000pv程度の弱小サービス。割と楽しくやってるからおっけ。Twitterのフォロワーが増えなさすぎることが勉強になった(1000は行くと思った)

エンジニアにありがちなバックエンドのみの変更を繰り返したことは失敗。ユーザーに提供するのが一番大事。前職で無駄機能を付けるのは無意味ってことを分かってたんだが、億劫になり過ぎた。っか勘違いしてた。無駄機能と呼べるのは成熟期の話でしょっぱなはとりあえず作り込まなきゃダメ。話はそれから。

アーキテクチャは以下のブログ書いた

ブログ結構書いた

ほとんど.NET Core、たまにreact。普通に.NET Core最高過ぎて他のフレームワーク触る気起きない。技術的にはそんなに向上してない。Windows嫌いになった。

本当にやりたいことが見えてきた

仕事したくない
ほんとこれ。エンジニアとして一流になりたいとか全然ない。あとプログラムが好きなわけじゃなくて物作りが好きなので、たまたま一番お金かからないプログラムをやってただけなんだなと実感出来た。なので今年はアプリを作ろうと思ってる。言語はなんでもいいや、楽なやつがいい。

お金

結構使った。パソコンはWindowsLinux)とMacの二台買った。デスクトップはいらないなと思った。Azureに6万、GitHubに5000円ぐらい、freeeに一万。パソコンはしばらくいらないのでなんかキャンペーンとかにお金を使おうと思ってる。結構真面目にみんなの洋楽ランキングは成長させたい!洋楽好きだし。

人脈

むしろ減った。たまに勉強会とか行ったけど家でやったほうが捗るわ。何人かと絡んだけど意外に異業種の人と付き合った方がいい。前職からやたら声かかる。普通にすげー仕事させられるから行く気ゼロ。みんなの洋楽ランキング経由でTwitterで何人かと絡んだ。凄腕のエンジニアと未経験のエンジニアの違いがイマイチわからんくなった。凄腕のエンジニアより未経験おじさんのサイトの方がサイトまともってどゆこと!?とりあえず30半ば以上の人の行動力はイかれてる。

勉強

いろんなことが勉強になった。帳簿付けとか割と知らないことあってびっくり。技術面ではangularやっぱ良いなと実感。軌道に乗るといろいろ楽。reactもちょっとやった。俺は好きだけど、実務でやるとどうなんだろう。Azureも結構触った。何が良いの?って聞かれたらよくわかんないけど、値段も含めだいたいAzureで片付くのでそこぐらい。今年は資格取ろうかな。

プライベート

結婚した

28で結婚した。思ったより早かった。周りの見る目変わり過ぎ。今年に子どもが生まれるんでもっと楽しくなりそう。

洋楽よく聞いた

すげー聞いた。前も聞いてたけどspotifyにしてから恐ろしいぐらい聞いた。今年はいい曲が少なかったのでサラ・バレリスの「Love Song」を聞きまくった。これはマジで名曲。今年の曲だとこれかな。

結構休んだ

数週間とか平気で休むようになった。普通に休ませてくれる今の現場はかなり良い、さすが大企業。休み中はひたすらプログラムしてる感じかな。平日ほとんど出来ないし。

テラハめっちゃ見た

嫁と。部屋で引きこもってプログラムしてると怒られるからノート購入。机座らなくなった。Mac miniとディスプレイいらね。机も椅子もいらね。テラハかなりおもしろい全部見た。

健康

寝なくなった

基本定時帰りだけど、調べ物とかしてて夜中になる。睡眠不足みたいな。でも正社員みたいな面倒な人付き合いとかないから気持ち的にもプログラミングできて良かった。前職だとプログラム全くしたくなかったし、実際エンジニアの仕事してなかったし。

デブった

マジ太った。社会人になって6年だけど体重15キロ増えた。これはやばい。

タバコ吸い過ぎた

一日20本。アイコスにして複数吸い出来ないあの感じが減ったから無限に吸えちゃう。休日なんか一箱以上吸っちゃう。アイコスにしても意味ね。

食生活はまとも

基本作ってくれるので野菜とかめっちゃ食べてる。順調に太ってきた。やばい。

総括

わりと濃い一年。今年はどうしようか。サービス作るか。エンタメ系のサービスが良いな。〇〇を解決するサービスは作る気ゼロ。というかイかれてるクオリティ出さないと到底お金は取れない。3Dプリンタとかそこら辺が多分楽しいと思う。ぶっちゃけゲーム以外のソフトウェアは結構限界にきてると思う。ラズパイとか面白いと思う。

ASP.NET CoreのGoogle認証

f:id:tekitoumemo:20190106005729p:plain

前回、外部ログインのセットアップとFacebook認証までは説明したので今回はGoogle認証の追加だけです。不足してる情報は以下に書いたのでよかったらみてください。
tekitoumemo.hatenablog.com

tekitoumemo.hatenablog.com

前準備

https://console.developers.google.com/projectselector/apis/libraryGoogle Cloud Platform
でアプリを作成します。これもだいたい以下のURLに書いてます。
docs.microsoft.com
ここも基本的には「/signin-google」でcallback Urlを設定してください。
f:id:tekitoumemo:20190106010614p:plain

クライアント IDとクライアント シークレットを取得しておいてください。

Googlehttpsのみ対応しています。ssl入れてない人はあきらめましょう(多分)

Startupに登録

ConfigureServicesに以下を追加

services.AddAuthentication().AddGoogle(googleOptions =>
{
    googleOptions.ClientId = Configuration["Authentication:Google:ClientId"];
    googleOptions.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
});

Viewを作成

// これか
<a asp-action="SignIn" asp-route-provider ="Google">Google</a>
// これでもおけ
<a href="/auth/signin?provider=Google">Google</a>

これで前回のTwitterの記事と同じ要領で実装終了です。

めっちゃ楽!

Twitterの記事で書いたcallbackUrlとFacebookの記事で書いたhttpさえ解決出来ればすぐ実装出来ますね。

SNS認証は一通り出来たので次は他のことを実装しよう!
f:id:tekitoumemo:20190106011403p:plain
メアド認証がないとログイン画面が決まらんなぁ〜

次はrole関係を適当に書きます。

ASP.NET CoreのFacebook認証

f:id:tekitoumemo:20190105232452p:plain
前回、外部ログインのセットアップまでは説明したので今回はFacebook認証の追加だけです。

tekitoumemo.hatenablog.com

よく個人でサイトを作っている人を見るとFacebookは実装されてないことをよく見るのですが、ここは詰まる人が多いと思います。

前準備

Facebook for Developersでアプリを作成します。これもだいたい以下のURLに書いてます。
docs.microsoft.com

ここも基本的には「/signin-facebook」でcallback Urlを設定してください。
f:id:tekitoumemo:20190105232736p:plain
アプリIDとapp secretを取得しておいてください。

Facebookhttpsのみ対応しています。ssl入れてない人はあきらめましょう

Startupに登録

ConfigureServicesに以下を追加

services.AddAuthentication().AddFacebook(facebookOptions =>
{
    facebookOptions.AppId = Configuration["Authentication:Facebook:AppId"];
    facebookOptions.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
});

複数のSNSログインを実装している場合は以下のようにメソッドチェーンで実装出来ます。

services.AddAuthentication()
    .AddMicrosoftAccount(microsoftOptions => { ... })
    .AddGoogle(googleOptions => { ... })
    .AddTwitter(twitterOptions => { ... })
    .AddFacebook(facebookOptions => { ... });

Viewを作成

// これか
<a asp-action="SignIn" asp-route-provider ="Facebook">Facebook</a>
// これでもおけ
<a href="/auth/signin?provider=Facebook">Facebook</a>

これで前回のTwitterの記事と同じ要領で実装終了です。

本番だと動かない!

テストだと動くのですが、本番だと動きませんでした。要因はいくつかあると思うのですが、僕の場合はRedirectUrlがhttpで403になったことが原因でした。F12で調べてみてください。添付した画像はhttpsですが、403の場合httpになっている可能性があります。
f:id:tekitoumemo:20190105233552p:plain
「なんだよこれ」と思って自力でOAuthを実装しようかと思って気がつきました。

リクエストをhttpsにする

app.Use((context, next) =>
{
    context.Request.Scheme = "https";
   return next();
});

これ以外にも以下の対処法があるみたいです。

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
     ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseHttpMethodOverride();

これはKestrelとリバプロが関係しているからXForwardedForで対処できるのかよくわかりません。よくわからなかったのでhttpsに変換する方法で対応しました(全部httpsでも困らないし)これがnginxだけなのかよくわかりません。

おそらくこれを対処しないとGoogleも出来ないですし、いつかTwitterもダメになっちゃうので気づいてよかったです。

ASP.NET CoreのTwitter認証と会員機能を作った理由

f:id:tekitoumemo:20190104232825p:plain
みんなの洋楽ランキングにSNS認証(TwitterFacebookGoogle)を追加しました。今回は外部ログインのセットアップとTwitter認証を説明をします。今回は2019年1月現在のやり方なので今後変わるかもしれません。

まずは審査から

最近は審査が厳しいので、以前書いた記事を参考にしてください。英語が全く出来ない僕でも審査が通ったので手順を踏めば誰でも取れるはずです。
tekitoumemo.hatenablog.com

.NET Coreの外部ログインのセットアップ

Twitter Developerを設定する

ほとんど以下に載っています。
docs.microsoft.com
2018/08からcallbackに設定しなければいけないので以下のように設定します。
f:id:tekitoumemo:20190104235030p:plain
デフォルトのcallback urlは「signin-twitter」です。これ間違えると403になります。またこのセットアップ方法を使う場合はhttpでリダイレクトするのでhttpにしないとエラーになります。僕は対策済みなのでhttpsですが、こちらは次回のFacebookログインで説明します。

Startupに登録

ConfigureServicesに以下を追加

services.AddAuthentication(options =>
{
    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddTwitter(twitterOptions =>{
    twitterOptions.ConsumerKey = "your_apikey";
    twitterOptions.ConsumerSecret = "your_sercret_key";
});

AddAuthenticationはcookie 認証スキームにしています。ここら辺はすきな方法で良いかと思います。認証キーはhttps://developer.twitter.comから取得してください。

Configureに以下を追加

app.UseAuthentication();

認証用のControllerを作成

ログイン

IAuthenticationSchemeProviderをインジェクションします。

public class AuthController : Controller
{
        private IAuthServices _authServices;

        public AuthController (IAuthenticationSchemeProvider authenticationSchemeProvider) {
            _authenticationSchemeProvider = authenticationSchemeProvider;
        }
    public IActionResult Login()
    {
    }
}

Viewも作ります。

// これか
<a asp-action="SignIn" asp-route-provider ="Twitter">Twitter</a>
// これでもおけ
<a href="/auth/signin?provider=Twitter">Twitter</a>

サインイン

public IActionResult SignIn (string provider) {
    return Challenge (new AuthenticationProperties { RedirectUri = "/" }, provider);
}

providerは「Twitter」などSNSの名称が割り当てられます。RedirectUriはサインイン後のリダイレクト先でcallbackurlとは違うのでご注意を。

サインアウト

public async Task<IActionResult> SignOut () {
    await HttpContext.SignOutAsync (CookieAuthenticationDefaults.AuthenticationScheme);
    return RedirectToAction ("Index", "Home");
}

returnは適当に設定して下さい。

認証後の確認

以下で認証しているか確認できます。

Request.HttpContext.User.Identity.IsAuthenticated

さらに認証で取得した情報は以下で確認できます。

Request.HttpContext.User.Claims

TwitterだとEmailは取得できません。が、取得できる方法がありそうなので興味ある人は調べてみてはいかがでしょう。

認証後のそのほか

AuthorizeAttributeなどRoleベースの説明をすると長くなるのでこちらはまた別の機会で説明します。僕の場合は会員に権限(Role)をつけて、管理者のみ管理画面を使えるようにしています。

最後に会員認証を追加したきっかけを話します(自己満)

追加したきっかけ

自分たちで記事を書くのに限界を感じたので、ユーザーさんに記事を書いてもらいたいなぁと思いアンケートをとりました。アンケートの結果、記事を書いても良いと言う意見が100%(もちろん対価を得たいという意見が多いですが)だったので、ユーザーさんが記事をかける環境が必要でした。
f:id:tekitoumemo:20190104234001p:plain
Wikiみたく誰でもかける環境にしてもよかったのですが、自分の名前を出さない事により記事の質が下がる懸念と会員からユーザーのコミュニティに広げられそうな可能性を感じ認証を作りました。SNS認証のみ作成した理由は、メアド会員自体、時代に反している気がして僕自身SNS認証がないサイトは使いたくなかったです。ただ、やってるうちに必要か不必要か判断できるようになるので必要になったら追加しようと思います。

次回はFacebookログインを書きます
tekitoumemo.hatenablog.com

CoreTweetの検索をインジェクションで

.NETのTwitterライブラリにCoreTweetってのがあります。TwitterAPIのラッパーです。

www.nuget.org

最近、コンテンツ追加にCoreTweetを使ったので簡単な検索方法を説明します。以下のような感じで「続きを読む」を押すと過去5件でツイートが表示されます。
f:id:tekitoumemo:20190103214243p:plain


.NET Coreで実装したのでSeviceに登録してインジェクションするやり方です。

ダウンロード

dotnet add package CoreTweet --version 1.0.0.483

大枠を作成

// class
public class Twitter : ITwitter {
    private Tokens _tokens;
    public Twitter (string consumerKey, string consumerSecret, string accessToken, string accessSecret) {
        _tokens = Tokens.Create (consumerKey, consumerSecret, accessToken, accessSecret);
    }
}
// interface
public interface ITwitter { }

consumerKey、consumerSecret、accessToken、accessSecretはhttps://apps.twitter.com/から取得してください。interfaceは後から追加するので今は枠組みだけです。

Startup.csに登録

services.AddSingleton<ITwitter> (_ =>
   new Twitter (consumerKey, consumerSecret, accessToken, accessSecret));
}

これでインジェクションできる準備ができました。今回はシングルトンで問題ないのでシングルトンにしました。

検索メソッドを追加

public class Twitter : ITwitter {
    private Tokens _tokens;
    public Twitter (string consumerKey, string consumerSecret, string accessToken, string accessSecret) {
        _tokens = Tokens.Create (consumerKey, consumerSecret, accessToken, accessSecret);
    }
    // これ追加
    public async Task<SearchResult> SearchTweets (params Expression<Func<string, object>>[] parameters) {
        return await _tokens.Search.TweetsAsync (parameters);
    }
}
// interface
public interface ITwitter {
    Task<SearchResult> SearchTweets (params Expression<Func<string, object>>[] parameters);
}

Twitterは結構いろんなところで使いそうなのでinterfaceだけ定義してインジェクションして使えるようにしました。引数はExpression>にしてTweetsAsyncと全く同じように使えるようにします。

呼び出し側

public class TwitterRepository : ITwitterRepository {
    private ITwitter _twitter;
    public TwitterRepository (Twitter twitter) {
        _twitter = twitter;
    }
    public async Task SearchTweets (string keyword, long? maxId = null) {
        var tweets = await _twitter.SearchTweets (count => 100,
            q => keyword,
            max_id => maxId,
            lang => "ja",
            exclude => "retweets",
            tweet_mode => "extended");
    }
}

コンストラクタでインジェクションしてSearchTweetsで使ってます。オプションがいくつかあるので以下で説明します。以下のURLに全部乗ってます。
API reference index — Twitter Developers

max_id:twitterIdを指定するとtwitterIdより過去の記事を取得します。
lang:言語を指定します。jaは日本語です。
exclude:リツイートを除外します。僕は不要なんで必要なかったです。
tweet_mode:デフォルトだと140文字を取得できないので"extended"を指定して全部取れるようにします。

そのほか

これらはオプションであるかもしれません。

でかい画像に変換

ser.ProfileImageUrlで画像を取れるのですが、「normal.jpg」だと画像が小さいので「bigger.jpg」に置換しています。

User.ProfileImageUrl.Replace("normal.jpg", "bigger.jpg")
メタを置換

&は微妙なので

FullText.Replace("&amp;", "&")
本文にキーワードが含まれているものを抽出
Where(x => x.FullText.ToUpper().Contains(keyword.ToUpper())).

結構簡単に使えるので良いですね。次は.NET Coreでの認証を書きます。

ASP.NET Coreのinclude属性とexclude属性

ASP.NET Coreのタグヘルパーでinclude、exclude属性ってのがあります。これは、実行環境毎に定義するタグを切り替えられるもので開発、ステージング、本番など環境に応じて変更出来ます。僕の場合、BuildBundlerMinifierを使っているのでcssがミニファイされて開発時にいちいちビルドしなければいけなかったのですが、これのおかげで開発用のcss、本番用のcssと切り替えられるようになりました。今回は、本番でミニファイされたCSS、開発で生CSSを使うように説明します。

include属性

タグのinclude属性に表示されるための条件を設定します。

開発の場合

<environment include="Development">
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
</environment>

ステージング、本番の場合

<environment include="Staging,Production">
    <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true">
</environment>

ちなみにasp-append-version="true"は「v=Q55BkiaTp6uRl9...」をつけてくれるのでキャッシュ対策です。

BuildBundlerMinifier

BuildBundlerMinifierはこれです。Microsoft サポートが絡んでいるので信頼があります。BundlerMinifier.Coreってのがあるのですがこれは公式サポートがないので使う人は自己責任って感じですかね。
www.nuget.org
こんな感じでミニファイするファイルを指定するのですが、これがいちいちビルドしなければいけなかったのがめんどかったのでよかった。
f:id:tekitoumemo:20181228001107p:plain

マイクロソフトの公式はいまいち読む気がしないのですが、ちゃんと読まなきゃダメですね。

参考
バンドルし、縮小の ASP.NET Core で静的なアセット | Microsoft Docs