<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gbubemi</title>
    <description>The latest articles on DEV Community by Gbubemi (@smiththe_4th).</description>
    <link>https://dev.to/smiththe_4th</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F438211%2Feaf3ebbb-04f9-4fc3-b3e1-90a75e98b8df.jpeg</url>
      <title>DEV Community: Gbubemi</title>
      <link>https://dev.to/smiththe_4th</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/smiththe_4th"/>
    <language>en</language>
    <item>
      <title>Use multiple .NET SDK CLI Commands on Mac M1</title>
      <dc:creator>Gbubemi</dc:creator>
      <pubDate>Mon, 04 Apr 2022 23:47:55 +0000</pubDate>
      <link>https://dev.to/smiththe_4th/use-multiple-net-sdk-cli-commands-on-mac-m1-64j</link>
      <guid>https://dev.to/smiththe_4th/use-multiple-net-sdk-cli-commands-on-mac-m1-64j</guid>
      <description>&lt;p&gt;Personally, It has been a bit frustrating working with multiple .NET core SDKs on the M1, especially when you use dotnet cli commands a lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Installing .NET 5 and .NET 6 creates two folders &lt;strong&gt;/usr/local/share/dotnet/x64/sdk&lt;/strong&gt; and &lt;strong&gt;/usr/local/share/dotnet/sdk&lt;/strong&gt; respectively and executing the dotnet commands on the cli can be annoying. If .NET 5 takes precedence on the cli you can't run a command for .NET 6 unless you specify the full path and then the command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;I use ITerm2, ZSH and Oh my Zsh because it has more features and better functionalities than the default terminal and you can set this up using this amazing post below:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.freecodecamp.org/news/how-to-configure-your-macos-terminal-with-zsh-like-a-pro-c0ab3f3c1156/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-media-1.freecodecamp.org%2Fimages%2F1%2AREqZX2_JqQjbH9Ly3QsgLg.png" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.freecodecamp.org/news/how-to-configure-your-macos-terminal-with-zsh-like-a-pro-c0ab3f3c1156/" rel="noopener noreferrer" class="c-link"&gt;
          How to Configure your macOs Terminal with Zsh like a Pro
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          By Chiamaka Ikeanyi Sometimes, using the default terminal sucks. You want to go out of the ordinary, to add life to the boring terminal and improve your productivity. Z shell (Zsh) is a Unix shell built on top of bash (the default shell for macOS) wi...
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.freecodecamp.org%2Funiversal%2Ffavicons%2Ffavicon.ico"&gt;
        freecodecamp.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  STEPS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open the zshrc file using the command below and if you don't have the file you can use the link above to create one
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;open ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a permanent alias for the dotnet directory path that's not the default on your terminal. In my case, .NET 5 is the default and to run .NET 6 commands easily, add the below to your .zshrc file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias dotnet6="/usr/local/share/dotnet/dotnet"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;note:&lt;/strong&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;dotnet6&lt;/strong&gt; can be any name you want and &lt;strong&gt;/usr/local/share/dotnet/dotnet&lt;/strong&gt; is the path that targets .NET 6.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Restart the terminal and then run
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet6 --info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;.NET 6 command check&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf9v43rusvqre7tc8ca7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf9v43rusvqre7tc8ca7.png" alt="*.NET 6 command check*"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;.NET 5 command check&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8o9gb0tmft5n55g25kp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8o9gb0tmft5n55g25kp.png" alt="*.NET 5 command check*"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>m1</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>zsh</category>
    </item>
    <item>
      <title>Deploy ASP.Net Core with MySql to Heroku</title>
      <dc:creator>Gbubemi</dc:creator>
      <pubDate>Wed, 10 Feb 2021 12:59:42 +0000</pubDate>
      <link>https://dev.to/smiththe_4th/deploy-asp-net-core-with-mysql-to-heroku-44dp</link>
      <guid>https://dev.to/smiththe_4th/deploy-asp-net-core-with-mysql-to-heroku-44dp</guid>
      <description>&lt;p&gt;Heroku is a great tool to host personal projects and there's a free tier. However, .Net Core is not supported for now but, there's a work around this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A Heroku account - &lt;a href="https://signup.heroku.com/" rel="noopener noreferrer"&gt;https://signup.heroku.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install the Heroku CLI - &lt;a href="https://devcenter.heroku.com/articles/heroku-cli" rel="noopener noreferrer"&gt;https://devcenter.heroku.com/articles/heroku-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;git enabled&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new app on the Heroku website &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffdd8mekuxf76p9o4utdo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffdd8mekuxf76p9o4utdo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
and ensure the app name is unique.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the terminal on your system, change directory to your core project and log into Heroku account.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;heroku login&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the Heroku Git remote&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;heroku git:remote -a {your app name}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We need a dotnet buildpack because, dotnet is not supported.&lt;br&gt;
For this tutorial, I used and my .net core version is 3.1.3  &lt;a href="https://elements.heroku.com/buildpacks/jincod/dotnetcore-buildpack" rel="noopener noreferrer"&gt;https://elements.heroku.com/buildpacks/jincod/dotnetcore-buildpack&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Use this command if your .net core version is the same as mine&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;heroku buildpacks:set &lt;a href="https://github.com/jincod/dotnetcore-buildpack%5C#v3.1.3" rel="noopener noreferrer"&gt;https://github.com/jincod/dotnetcore-buildpack\#v3.1.3&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are on a .net 5. You can use this command&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;heroku buildpacks:set jincod/dotnetcore&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ensure you are on heroku-18 stack &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;heroku stack:set heroku-18&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To a database resource: Navigate to the resources tab then search for ClearDB MySql and select the free version.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F37jpfxwk7efyvgjj9itf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F37jpfxwk7efyvgjj9itf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To get the connection string, you need to navigate to the settings and click on Reveal Config Vars.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F64wad6v5915l90fwqksn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F64wad6v5915l90fwqksn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, add ASPNETCORE_ENVIRONMENT config and set it to Production.&lt;/p&gt;

&lt;p&gt;ClearDb connection string is usually in this format :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;mysql://username:password@host/databasename?reconnect=true&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you can use the code snippet below to build the connection string for EF core&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services.AddDbContext&amp;lt;DbContext&amp;gt;(x =&amp;gt;
            {

                var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
                string connStr;

                if (env == "Development")
                {
                    connStr = Configuration.GetConnectionString("DemoConnection");


                }
                else
                {
                    // Use connection string provided at runtime by Heroku.
                    var connUrl = Environment.GetEnvironmentVariable("CLEARDB_DATABASE_URL");

                    connUrl = connUrl.Replace("mysql://", string.Empty);
                    var userPassSide = connUrl.Split("@")[0];
                    var hostSide = connUrl.Split("@")[1];

                    var connUser = userPassSide.Split(":")[0];
                    var connPass = userPassSide.Split(":")[1];
                    var connHost = hostSide.Split("/")[0];
                    var connDb = hostSide.Split("/")[1].Split("?")[0];


                    connStr = $"server={connHost};Uid={connUser};Pwd={connPass};Database={connDb}";



                }

                x.UseMySql(connStr);

            });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now we are set to publish to heroku. Use the command below to achieve this&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;git push heroku master &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once publishing has been completed, your app url can be found in the settings tab.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcalo27xo5rwoz7g6gm6y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcalo27xo5rwoz7g6gm6y.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>heroku</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Twitter Sign In with .net core 3.1 and Angular</title>
      <dc:creator>Gbubemi</dc:creator>
      <pubDate>Sun, 02 Aug 2020 15:19:47 +0000</pubDate>
      <link>https://dev.to/smiththe_4th/twitter-sign-in-with-net-core-3-1-and-angular-2g5p</link>
      <guid>https://dev.to/smiththe_4th/twitter-sign-in-with-net-core-3-1-and-angular-2g5p</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fwDrWO3y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bdbdcoy856ryh4tesjbs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fwDrWO3y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bdbdcoy856ryh4tesjbs.png" alt="Alt Text" width="880" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Implementations of Sign in with twitter are based on OAuth. &lt;/p&gt;

&lt;p&gt;Working with OAuth 1.0a can get really clumsy and you have to get the signature handling right. I found a really nice and easy to implement OAuth library for dotnet &lt;a href="https://github.com/rhargreaves/oauth-dotnetcore"&gt;https://github.com/rhargreaves/oauth-dotnetcore&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GETTING STARTED&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, you have to apply for a developer account on &lt;a href="https://developer.twitter.com/"&gt;https://developer.twitter.com/&lt;/a&gt; and register your app. You will then get a consumer key and consumer secret. In this post I would complete the sign in with twitter in 3 steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 1:Obtaining a request token&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To obtain a request token we need to make a post request to &lt;a href="https://api.twitter.com/oauth/request_token"&gt;https://api.twitter.com/oauth/request_token&lt;/a&gt;. The body of the successful response will contain the oauth_token, oauth_token_secret, and oauth_callback_confirmed parameters.&lt;/p&gt;

&lt;p&gt;Create a model for the request token response.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class RequestTokenResponse
{
    public string oauth_token { get; set; }
    public string oauth_token_secret { get; set; }
    public string oauth_callback_confirmed { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I would be using dependency injection so, first off, create a folder named Data then, create an interface named ITwitterAuthRepository and a class TwitterAuthRepository.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface ITwitterAuthRepository
{
    Task&amp;lt;RequestTokenResponse&amp;gt; GetRequestToken();

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;TwitterAuthRepository class and add implementation.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class TwitterAuthRepository : ITwitterAuthRepository
{
    private readonly IConfiguration _config;
    private readonly IHttpClientFactory _clientFactory;
    private readonly IOptions&amp;lt;TwitterSettings&amp;gt; _twitterConfig;
    private readonly DataContext _context;

    public TwitterAuthRepository(IConfiguration config, IHttpClientFactory clientFactory, IOptions&amp;lt;TwitterSettings&amp;gt; twitterConfig, DataContext context)
    {
        _context = context;
        _twitterConfig = twitterConfig;
        _clientFactory = clientFactory;
        _config = config;

    }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To start a sign-in flow, your Twitter app must obtain a request token by sending a signed message to POST oauth/request_token. The only unique parameter in this request is oauth_callback, which must be a URL-encoded version of the URL you wish your user to be redirected to when they complete step 2. The remaining parameters are added by the OAuth signing process.&lt;/p&gt;

&lt;p&gt;Twitter settings model.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class TwitterSettings
{
    public string AppId { get; set; }
    public string AppSecret { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add this in your appsettings.json&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"TwitterSettings": {
      "AppId": "",
      "AppSecret": ""
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;configure this in your startup class&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services.Configure&amp;lt;TwitterSettings&amp;gt;(Configuration.GetSection("TwitterSettings"));
services.AddHttpClient("twitter");
services.AddScoped&amp;lt;ITwitterAuthRepository, TwitterAuthRepository&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Install the nuget package OAuth.DotNetCore.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task&amp;lt;RequestTokenResponse&amp;gt; GetRequestToken()
{

        var requestTokenResponse = new RequestTokenResponse();


        var client = _clientFactory.CreateClient("twitter");
        var consumerKey = _twitterConfig.Value.AppId;
        var consumerSecret = _twitterConfig.Value.AppSecret;
        var callbackUrl = "http://localhost:4200/login";

        client.DefaultRequestHeaders.Accept.Clear();

        var oauthClient = new OAuthRequest
        {
            Method = "POST",
            Type = OAuthRequestType.RequestToken,
            SignatureMethod = OAuthSignatureMethod.HmacSha1,
            ConsumerKey = consumerKey,
            ConsumerSecret = consumerSecret,
            RequestUrl = "https://api.twitter.com/oauth/request_token",
            Version = "1.0a",
            Realm = "twitter.com",
            CallbackUrl = callbackUrl
        };

        string auth = oauthClient.GetAuthorizationHeader();

        client.DefaultRequestHeaders.Add("Authorization", auth);



        try
        {
            var content = new StringContent("", Encoding.UTF8, "application/json");

            using (var response = await client.PostAsync(oauthClient.RequestUrl, content))
            {
                response.EnsureSuccessStatusCode();

                var responseString = response.Content.ReadAsStringAsync()
                                           .Result.Split("&amp;amp;");


                requestTokenResponse = new RequestTokenResponse
                {
                    oauth_token = responseString[0],
                    oauth_token_secret = responseString[1],
                    oauth_callback_confirmed = responseString[2]
                };


            }
        }
        catch (Exception ex)
        {

            throw;
        }

        return requestTokenResponse;

    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Create a controller &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Route("api/[controller]")]
[ApiController]
public class TwitterClientController : ControllerBase
{
    private readonly ITwitterAuthRepository _twitterAuth;
    private readonly IMapper _mapper;
    private readonly IConfiguration _config;
    private readonly DataContext _context;
    public TwitterClientController(ITwitterAuthRepository twitterAuth, IMapper mapper, 
    IConfiguration config, DataContext context)
    {
        _context = context;
        _config = config;
        _mapper = mapper;
        _twitterAuth = twitterAuth;

    }

[HttpGet("GetRequestToken")]
public async Task&amp;lt;IActionResult&amp;gt; GetRequestToken()
{
    //STEP 1 call made to /oauth/request_token
    var response = await _twitterAuth.GetRequestToken();

    return Ok(response);

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Redirecting the user&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a service and a model on your SPA.&lt;/p&gt;

&lt;p&gt;Service&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class TwitterAuthService {
   baseUrl = "http://localhost:5000/api/";

   constructor(private http: HttpClient) { }

getRequestToken(): Observable&amp;lt;RequestToken&amp;gt; {
   return this.http.get&amp;lt;RequestToken&amp;gt;(this.baseUrl +'twitterclient/GetRequestToken');
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Model&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface RequestToken {
  oauth_token: string,
  oauth_token_secret: string,
  oauth_callback_confirmed: string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Create a login component&lt;/p&gt;

&lt;p&gt;Add this to your login.component.ts file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; export class LoginComponent implements OnInit {

   private requestToken: Partial&amp;lt;RequestToken&amp;gt; = {};
   disableButton = false;
   isLoading = false;

   constructor(private twitterService: TwitterAuthService,   private route: ActivatedRoute, private router: Router) { }

   ngOnInit() {

   }

launchTwitterLogin() {
 this.isLoading = true;
 this.disableButton = true;
 this.twitterService.getRequestToken()
  .subscribe(response =&amp;gt; this.requestToken = response, 
    error =&amp;gt; console.log(error), 
    () =&amp;gt; {
    location.href = "https://api.twitter.com/oauth/authenticate?" + this.requestToken.oauth_token;
    }
  );
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;create a sign in button in your login.component.html&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;button class="btn btn-info btn-block (click)="launchTwitterLogin()" type="button" [disabled]="disableButton"&amp;gt; &amp;lt;i *ngIf="isLoading" class="fa fa-spinner fa-spin fa-lg fa-fw"&amp;gt;&amp;lt;/i&amp;gt; &amp;lt;i class="fa fa-twitter"&amp;gt;&amp;lt;/i&amp;gt; Sign in with &amp;lt;b&amp;gt;Twitter&amp;lt;/b&amp;gt;
      &amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Converting the request token to an access token&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To render the request token into a usable access token, your application must make a request to the &lt;strong&gt;POST oauth/access_token&lt;/strong&gt; endpoint, containing the oauth_verifier value obtained in step 2. The request token is also passed in the oauth_token portion of the header, but this will have been added by the signing process.&lt;/p&gt;

&lt;p&gt;Model&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; public class UserModelDto
 {
    public string Username { get; set; }
    public string UserId { get; set; }
    public string Token { get; set; }
    public string TokenSecret { get; set; }

 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add this to TwiterAuthRepository.cs&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; //Get Access Token
    public async Task&amp;lt;UserModelDto&amp;gt; GetAccessToken(string token, string oauthVerifier)
    {
        var client = _clientFactory.CreateClient("twitter");
        var consumerKey = _twitterConfig.Value.AppId;
        var consumerSecret = _twitterConfig.Value.AppSecret;

        var accessTokenResponse = new UserModelDto();

        client.DefaultRequestHeaders.Accept.Clear();

        var oauthClient = new OAuthRequest
        {
            Method = "POST",
            Type = OAuthRequestType.AccessToken,
            SignatureMethod = OAuthSignatureMethod.HmacSha1,
            ConsumerKey = consumerKey,
            ConsumerSecret = consumerSecret,
            RequestUrl = "https://api.twitter.com/oauth/access_token",
            Token = token,
            Version = "1.0a",
            Realm = "twitter.com"
        };

        string auth = oauthClient.GetAuthorizationHeader();

        client.DefaultRequestHeaders.Add("Authorization", auth);


        try
        {
            var content = new FormUrlEncodedContent(new[]{
                new KeyValuePair&amp;lt;string, string&amp;gt;("oauth_verifier", oauthVerifier)
            });

            using (var response = await client.PostAsync(oauthClient.RequestUrl, content))
            {
                response.EnsureSuccessStatusCode();

                //twiiter responds with a string concatenated by &amp;amp;
                var responseString = response.Content.ReadAsStringAsync()
                                           .Result.Split("&amp;amp;");

                //split by = to get actual values
                accessTokenResponse = new UserModelDto 
                {
                    Token = responseString[0].Split("=")[1],
                    TokenSecret = responseString[1].Split("=")[1],
                    UserId = responseString[2].Split("=")[1],
                    Username = responseString[3].Split("=")[1]
                };

            }
        }
        catch (Exception ex)
        {


        }

        return accessTokenResponse;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add this to your controller&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   [HttpGet("sign-in-with-twitter")]
public async Task&amp;lt;IActionResult&amp;gt; SignInWithTwitter(string oauth_token, string oauth_verifier)
{

    var response = await _twitterAuth.GetAccessToken(oauth_token, oauth_verifier);


    return Ok(response);

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Update the constructor on your login component&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  constructor(private twitterService: TwitterAuthService, private route: ActivatedRoute, private router: Router) { 

this.route.queryParamMap.subscribe(params =&amp;gt; {
  const oauth_token = this.route.snapshot.queryParamMap.get('oauth_token');
  const oauth_verifier = this.route.snapshot.queryParamMap.get("oauth_verifier");
  if (oauth_token &amp;amp;&amp;amp; oauth_verifier) {
    this.disableButton = true;
    this.isLoading = true;
    this.twitterService.getAccessToken(oauth_token, oauth_verifier).subscribe(null, error =&amp;gt; console.log(error)
    ,() =&amp;gt; {
      this.router.navigate(['/home']);
    });



  }
});

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A successful response contains the oauth_token, oauth_token_secret parameters. The token and token secret should be stored and used for future authenticated requests to the Twitter API. To determine the identity of the user, use GET account/verify_credentials.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>dotnet</category>
      <category>twitter</category>
      <category>oauth</category>
    </item>
  </channel>
</rss>
