<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Mehmet Ali Peker</title>
        <link>https://paragraph.com/@peker</link>
        <description>undefined</description>
        <lastBuildDate>Wed, 15 Apr 2026 01:48:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Mehmet Ali Peker</title>
            <url>https://storage.googleapis.com/papyrus_images/c5f437fc2bdd04fc7434699fccacc45b62c3a40d5c09cbec4b94651b4a6b5f67.jpg</url>
            <link>https://paragraph.com/@peker</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[OAuth güzel. Peki Ethereum'u denediniz mi?]]></title>
            <link>https://paragraph.com/@peker/oauth-g-zel-peki-ethereum-u-denediniz-mi</link>
            <guid>jR7wpEjNMSKIGb8uaRI1</guid>
            <pubDate>Tue, 09 Nov 2021 00:27:49 GMT</pubDate>
            <description><![CDATA[Web uygulamalarının temel ihtiyaçlarının başında kaçınılmaz olarak kimlik doğrulama Authentication gelmekte. Kısaca web uygulamamızla iletişime geçen kullanıcının gerçekten de iddia ettiği kullanıcı olduğundan emin olmak istiyoruz. Başlangıçta e-posta adresi/kullanıcı adı ve parola ikilileri ile bu problemi çözdük.HackerNews Giriş EkranıAncak genel olarak parolalar biraz şeydiler yani bilirsiniz, şey. Uzun ve güçlü bir kombinasyona sahip olmalıdırlar ki hacklenmeyesiniz. Her sitede farklı par...]]></description>
            <content:encoded><![CDATA[<p>Web uygulamalarının temel ihtiyaçlarının başında kaçınılmaz olarak kimlik doğrulama <code>Authentication</code> gelmekte. Kısaca web uygulamamızla iletişime geçen kullanıcının gerçekten de iddia ettiği kullanıcı olduğundan emin olmak istiyoruz. Başlangıçta e-posta adresi/kullanıcı adı ve parola ikilileri ile bu problemi çözdük.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="">HackerNews Giriş Ekranı</figcaption></figure><p>Ancak genel olarak parolalar biraz <em>şeydiler</em> yani bilirsiniz, <em>şey.</em> Uzun ve güçlü bir kombinasyona sahip olmalıdırlar ki hacklenmeyesiniz. Her sitede farklı parola kullanmalısınız ki parolanızı girdiğiniz site hacklenirse hacklenmeyesiniz. Bunu yaparken de tonla parola aklınızda tutamayacağınızdan bir <em>parola yönetici</em> kullanmalısınız ki onun da oradan al, oraya yapıştır, yeni siteye kaydolurken umarım eklenti düzgün kaydeder vs. Bir de onun güvenliği var ki ayrı dert. Parola yöneticisine de güvenmiyorsanız <code>two-blind</code> yöntemini kullanmanız lazım önemli siteler için. Dediğim gibi, parolalar biraz <em>şeyler</em>.</p><p>Genel olarak paroladan kurtulmamızı sağlayan bir çözümle karşılaştık. Çoğumuzun her gün kullandığı devasa şirketlerin logolarını içeren butonlar hayatımıza girdi. Kullanıcı için birkaç tık ile giriş yapma kolaylığını sağlayan bu butonlar, website sahiplerine de kullanıcı tabanlarını çok daha hızlı genişletme imkanını tanıyordu.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="">Popüler üçüncü parti giriş yapma yöntemleri</figcaption></figure><p>Dikkatinizi çekmek isterim ki buradaki email <em>(link gelmesi durumunda)</em> ve telefon numarası da aslında üçüncü parti bir giriş yapma yöntemi <em>–emailinizi kendi sunucunuzda barındırmıyor veya GSM operatörü sahibi değilseniz.</em> Şahsen Google ile giriş yapmayı severek kullanıyorum ancak bu tip yöntemlerin barındırdığı kimi riskler bulunmakta. Hesabınıza erişirken kullandığınız anahtarların başkasının kontrolünde olması gibi.</p><p>Bunu biraz şuna benzetebiliriz, bir eviniz var ve anahtarını başkasına veriyorsunuz. Evinize her girmek istediğinizde ise ondan izin almak zorundasınız. &quot;<em>Bugün olmaz, yarın gel&quot;</em> dediğinde yapabileceğiniz pek de bir şey yok.</p><blockquote><p>Bu yazıya başladıktan sonra Facebook ve diğer uygulamalarıyla servislerine yaklaşık 7 saat boyunca dünya genelinde erişilemedi. Diğer websiteleri ve uygulamalara Facebook ile kayıt olmuş kullanıcılar hesaplarına erişim sağlayamadı. Ayrıca Facebook, 2019 yılında da 24 saatten uzun bir süre offline olmuştu.</p></blockquote><h2 id="h-web-authentication" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Web Authentication</h2><p>Webin gelişimi ile birlikte alternatif yöntemler de implemente edildi. Bunlardan biri <code>Web Authentication</code> veya kısaca <code>WebAuthn</code> 2019&apos;dan beri popüler tarayıcılarda destekleniyor. Bu yöntem de OAuth gibi şifresiz bir giriş imkanı tanıyor. Bunu <code>public-private key</code> şifreleme mekanizmasıyla gerçekleştiriyor. Kullandığınız web sitesinin implementasyonuna göre aşağıdaki yöntemlerden bir veya birkaçını kullanarak bu sefer kullanıcı doğrulaması cihaz üzerinde gerçekleştiriliyor.</p><ul><li><p>Hardware Authenticator örneğin Yubikey</p></li><li><p>Software Authenticator örneğin telefondaki bir uygulama</p></li><li><p>Platform Authenticator örneğin Windows Hello, Face ID, hesap şifreniz ile cihazınızın kendisi</p></li></ul><p>Açıkçası etkileyici bir çözüm olsa da anladığım kadarıyla <code>Hardware Authenticator</code> kullanmadığınız sürece genel kullanıcı kitlesine erişimi kolay olan <code>Platform Authenticator</code> yönteminde kullandığınız cihazı kaybetmeniz durumunda giriş yaptığınız web sitelerine <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://charliedigital.com/2021/06/17/web-identity-showdown-ethereum-vs-webauthn/#:~:text=WebAuthn%3A%20the%20device%20dependency.%20Because%20the%20private%20keys%20are%20device%20specific%2C%20loss%20of%20the%20device%20equates%20to%20irrecoverable%20loss%20of%20access%20without%20an%20alternate%20mechanism.">erişiminiz de yok oluyor</a> <em>–ilgili sitede farklı bir kurtarma yöntemi yoksa.</em> <code>Hardware Authenticator</code> larda ise cihazlar/platformlar arası kimliğinizi taşımanız kolayken, ilgili cihazı <em>(örn. Yubikey)</em> kaybettiğinizde yine benzer bir durumla karşılaşıyorsunuz.</p><h2 id="h-favorim-ethereum-ile-giris" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Favorim: Ethereum ile Giriş</h2><p>Öncelikle biraz Ethereum&apos;dan bahsedelim. Nedir Ethereum? Ethereum&apos;a sadece bir kriptoparadır demek Ethereum&apos;un hakkını yemek olur. 2017&apos;den beri Ethereum&apos;a benzer bir göz ile baktığımdan ancak 2021&apos;de treni yakalayabildim.</p><p>Hadi Ethereum&apos;un kendini nasıl tanımladığına bakalım.</p><blockquote><p>Ethereum, geçmişiniz veya konumunuz ne olursa olsun, herkes için dijital paraya ve veri dostu hizmetlere açık erişimdir. Kripto para birimi etherinin (ETH) ve bugün kullanabileceğiniz binlerce uygulamanın arkasında topluluk tarafından oluşturulmuş bir teknolojidir.</p></blockquote><p>Ethereum en temelinde Ethereum blokzinciri ve üzerinde oluşan ekosistemi temsil eder. Ethereum blokzincirini üzerine kendi programlarınızı yazabileceğiniz kalıcı, herkese açık ve merkeziyetsiz bir veritabanı olarak düşünebilirsiniz. Tabii ki bir çok detayı bulunmakta ancak bu yazının konusu değil. Kendiniz araştırmanızı tavsiye ederim, keşfettikçe insanı heyecanlandıran bir ekosistem. <em>DYOR.</em></p><p>Son kullanıcı olarak Ethereum ağına dahil olabilmek için bir <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethereum.org/en/developers/docs/accounts/">hesaba</a> ihtiyacımız var. Hesaplar genel olarak şu iki seye sahiptir, adres ve bakiye. Bakiyenin nasıl belirlendiği oldukça bariz, peki adres nasıl oluşuyor?</p><p>Bir Ethereum hesabını oluşturan iki şey vardır, <code>public key</code> ve <code>private key</code>. Aslında SSL/TLS&apos;den aşina olduğumuz benzer bir yapı burada bulunmakta. Hesabınızın adresi sahip olduğunuz public keyden üzerinden üretilir. Public keyiniz de hesabınıza ait private keyden üretilir. Private keyinizi evde kendiniz de yapabilirsiniz ancak lütfen bunu yapmayın.</p><p>Belki bunun nereye gittigini görmüş olabilirsiniz. Elimizdekilere bakalım:</p><ul><li><p>Bir tanımlayıcı/<code>identifier</code> (address)</p></li><li><p>Herkese açık bir doğrulama anahtarı (public key)</p></li><li><p>Şifrelemek/imzalamak için kullanılan özel bir anahtar (private key)</p></li></ul><p>Gördüğünüz üzere aslında güvenli bir kimlik doğrulama mekanizması için gereken neredeyse her şeye sahibiz. Peki, eksik ne?</p><p>Eksik... mesaj! Özellikle her seferinde farklı olan bir mesaj veya bir diğer deyişle <code>payload</code> buradaki eksiğimiz. Bunu da kendimiz belirleyebiliriz. O zaman <strong>Ethereum ile girişi</strong> genel şemasını oluşturalım.</p><ul><li><p>Sunucu kullanıcıya imzalaması için bir mesaj gönderir.</p></li><li><p>Kullanıcı bu mesajı hesabının private keyi ile imzalar.</p></li><li><p>İmzalanmış mesajı ve adresini sunucuya gönderir.</p></li><li><p>Sunucu imzalanmış mesajı ve istediği mesajı kullanarak public keyi ve public key üzerinden de adresi çıkartır.</p></li><li><p>Sunucu çıkartılan adres ile iddia edilen adres aynı mı diye kontrol eder.</p></li><li><p>Ve tada 🎉</p></li></ul><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Konuşması kolay, kodu göster :) | <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://stickker.net/urun/talk-is-cheap-show-me-the-code/">https://stickker.net/urun/talk-is-cheap-show-me-the-code/</a></p><p>Öncelikle geliştirme ortamımızı hızlıca hazırlayalım. Node.js ve NPM&apos;in kurulu olduğunu varsayıyorum. Proje klasörümüzü ve express API&apos;mızı oluşturalım.</p><pre data-type="codeBlock" text="mkdir eth-sign-in &amp;&amp; cd eth-sign-in
npx express-generator --no-view
npm install
npm install ethers uuid
npm start
"><code>mkdir eth<span class="hljs-operator">-</span>sign<span class="hljs-operator">-</span>in <span class="hljs-operator">&#x26;</span><span class="hljs-operator">&#x26;</span> cd eth<span class="hljs-operator">-</span>sign<span class="hljs-operator">-</span>in
npx express<span class="hljs-operator">-</span>generator <span class="hljs-operator">-</span><span class="hljs-operator">-</span>no<span class="hljs-operator">-</span><span class="hljs-keyword">view</span>
npm install
npm install ethers uuid
npm start
</code></pre><p>Ardından <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://localhost:3000/">http://localhost:3000</a> adresinde Express yazısı bizi karşılıyor olacak.</p><h2 id="h-cuzdan-kurulumu" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Cüzdan Kurulumu</h2><p>Ethereum ağıyla etkileşime geçebilmek için bir <em>hesaba</em> ihtiyacımız olduğundan bahsetmiştim. Sahip olduğumuz hesapları kullanmayı, saklamayı, ağ ile iletişime geçmeyi kolaylaştıran uygulamalara ise <em>cüzdan</em> deniliyor. En popüler cüzdanlardan biri olan MetaMask işinizi görecektir. MetaMask tarayıcınıza eklenti olarak kurulup, ziyaret ettiğiniz web sitelerine Ethereum API&apos;nı enjekte ediyor.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://metamask.io/">Metamask Web Sitesi</a>&apos;nden tarayıcınıza yükledikten sonra sizi şu ekran karşılayacak:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Create a Wallet diyerek devam ediyoruz. Ardından bir parola belirlememizi istiyor. Parolamızı belirledikten sonra Ethereum hesabımıza herhangi bir zamanda herhangi bir yerden erişebilmemizi sağlayan &quot;Secret Recovery Phrase&quot; bizi karşılıyor. Bu kelimelere sahip herhangi biri hesabınıza erişebilir. Güvenli bir şekilde saklamanız önemli. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://metamask.zendesk.com/hc/en-us/articles/360060826432">Daha fazla bilgi.</a></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>xkcd: Security – <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://xkcd.com/538/">https://xkcd.com/538/</a></p><p>Kurulumu bitirdikten sonra artık bir Ethereum hesabına ve cüzdanına sahibiz! Aşağıdakine benzer bir ekran sizi karşılayacak. Sağ üstten bağlı olduğunuz blokzincir ağını görebilirsiniz. Örneğin kendi bilgisayarınızda çalışan bir blokzincire de MetaMask cüzdanınızla bağlanmanız mümkün. <em>How cool is that!</em></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Artık kodlamaya geçebiliriz! Öncelikle sayfamıza bir buton ekleyelim. Ardından tıklanıldığında cüzdandaki hesap adreslerine erişim isteyelim.</p><pre data-type="codeBlock" text="&lt;button onclick=&quot;signIn()&quot;&gt;Ethereum ile Giriş Yap&lt;/button&gt;

&lt;script&gt;
  async function signIn () {
    // Cüzdandaki hesap adreslerine erişim isteyelim.
    const accounts = await ethereum.request({ method: &apos;eth_requestAccounts&apos; })
    console.log(accounts)
  }
&lt;/script&gt;
"><code><span class="hljs-operator">&#x3C;</span>button onclick<span class="hljs-operator">=</span><span class="hljs-string">"signIn()"</span><span class="hljs-operator">></span>Ethereum ile Giriş Yap<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>button<span class="hljs-operator">></span>

<span class="hljs-operator">&#x3C;</span>script<span class="hljs-operator">></span>
  async <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">signIn</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Cüzdandaki hesap adreslerine erişim isteyelim.</span>
    const accounts <span class="hljs-operator">=</span> await ethereum.request({ method: <span class="hljs-string">'eth_requestAccounts'</span> })
    console.log(accounts)
  }
<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>script<span class="hljs-operator">></span>
</code></pre><p>public/index.html</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Butona tıkladıktan sonra çıkan popupı onaylayınca consoleda Ethereum hesap adresinizi görebilirsiniz. Şimdi sunucudan imzalanması gereken mesajı almamız gerekiyor. Bunun için endpointimizi oluşturalım.</p><pre data-type="codeBlock" text="// 18. satır sonrasına
const { v4: uuidv4 } = require(&apos;uuid&apos;);

// Şimdilik veritabanı olarak düşünelim
const addressNonceMap = {} 

app.post(&apos;/auth/ethereum/message&apos;, (req, res) =&gt; {
  // Kullanıcının Ethereum adresi
  let { address } = req.body
  address = address.toLowerCase()

  // Tek kullanımlık kod yoksa adrese ait, oluşturalım
  addressNonceMap[address] = addressNonceMap[address] ?? uuidv4() 

  const nonce = addressNonceMap[address]

    const message = `Welcome to there&apos;s no place like 127.0.0.1!\nClick &quot;Sign&quot; to sign in.\nWallet address: ${address}\n\nNonce: ${nonce}`
    
  res.send({
    message
  })
})
"><code><span class="hljs-comment">// 18. satır sonrasına</span>
const { v4: uuidv4 } <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'uuid'</span>);

<span class="hljs-comment">// Şimdilik veritabanı olarak düşünelim</span>
const addressNonceMap <span class="hljs-operator">=</span> {} 

app.post(<span class="hljs-string">'/auth/ethereum/message'</span>, (req, res) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
  <span class="hljs-comment">// Kullanıcının Ethereum adresi</span>
  let { <span class="hljs-keyword">address</span> } <span class="hljs-operator">=</span> req.body
  <span class="hljs-keyword">address</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>.toLowerCase()

  <span class="hljs-comment">// Tek kullanımlık kod yoksa adrese ait, oluşturalım</span>
  addressNonceMap[<span class="hljs-keyword">address</span>] <span class="hljs-operator">=</span> addressNonceMap[<span class="hljs-keyword">address</span>] ?? uuidv4() 

  const nonce <span class="hljs-operator">=</span> addressNonceMap[<span class="hljs-keyword">address</span>]

    const message <span class="hljs-operator">=</span> `Welcome to there<span class="hljs-string">'s no place like 127.0.0.1!\nClick "Sign" to sign in.\nWallet address: ${address}\n\nNonce: ${nonce}`
    
  res.send({
    message
  })
})
</span></code></pre><p>app.js</p><p>Şimdi ise butona tıklanıldığında sunucuya istek atıp gelen cevap ile imza isteği oluşturalım.</p><pre data-type="codeBlock" text="&lt;button onclick=&quot;signIn()&quot;&gt;Ethereum ile Giriş Yap&lt;/button&gt;

&lt;script src=&quot;https://cdn.ethers.io/lib/ethers-5.2.umd.min.js&quot; type=&quot;application/javascript&quot;&gt;&lt;/script&gt;

&lt;script&gt;
  async function signIn () {
    // Cüzdan erişimi isteyelim
    const accounts = await ethereum.request({ method: &apos;eth_requestAccounts&apos; })
    console.log(accounts)
    
    // Daha kolay işlem yapabilmek için ethers kütüphanesine Web3 Provider olarak MetaMask&apos;in sunduğu Ethereum Provider&apos;ını veriyoruz
    const provider = new ethers.providers.Web3Provider(window.ethereum)
    
    // Signerı hesap olarak düşünebilirsiniz. Ethereum ağında veya dışında hesabınızla yaptığınız her işlemde bir veri imzalanır.
    const signer = provider.getSigner()
    console.log(signer)

    // Sunucuya hesap adresini göndererek imzalanması gereken mesajı alalım.
    const response = await fetch(&apos;/auth/ethereum/message&apos;, {
      method: &apos;POST&apos;,
      headers: {
        &apos;content-type&apos;: &apos;application/json&apos;,
      },
      body: JSON.stringify({ address: accounts[0] })
    })

    const { message } = await response.json()
    
    // Signer&apos;dan imzalamasını isteyelim.
    const signature = await signer.signMessage(message)
    console.log(signature)
  }
&lt;/script&gt;
"><code><span class="hljs-operator">&#x3C;</span>button onclick<span class="hljs-operator">=</span><span class="hljs-string">"signIn()"</span><span class="hljs-operator">></span>Ethereum ile Giriş Yap<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>button<span class="hljs-operator">></span>

<span class="hljs-operator">&#x3C;</span>script src<span class="hljs-operator">=</span><span class="hljs-string">"https://cdn.ethers.io/lib/ethers-5.2.umd.min.js"</span> <span class="hljs-keyword">type</span><span class="hljs-operator">=</span><span class="hljs-string">"application/javascript"</span><span class="hljs-operator">></span><span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>script<span class="hljs-operator">></span>

<span class="hljs-operator">&#x3C;</span>script<span class="hljs-operator">></span>
  async <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">signIn</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Cüzdan erişimi isteyelim</span>
    const accounts <span class="hljs-operator">=</span> await ethereum.request({ method: <span class="hljs-string">'eth_requestAccounts'</span> })
    console.log(accounts)
    
    <span class="hljs-comment">// Daha kolay işlem yapabilmek için ethers kütüphanesine Web3 Provider olarak MetaMask'in sunduğu Ethereum Provider'ını veriyoruz</span>
    const provider <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> ethers.providers.Web3Provider(window.ethereum)
    
    <span class="hljs-comment">// Signerı hesap olarak düşünebilirsiniz. Ethereum ağında veya dışında hesabınızla yaptığınız her işlemde bir veri imzalanır.</span>
    const signer <span class="hljs-operator">=</span> provider.getSigner()
    console.log(signer)

    <span class="hljs-comment">// Sunucuya hesap adresini göndererek imzalanması gereken mesajı alalım.</span>
    const response <span class="hljs-operator">=</span> await fetch(<span class="hljs-string">'/auth/ethereum/message'</span>, {
      method: <span class="hljs-string">'POST'</span>,
      headers: {
        <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'application/json'</span>,
      },
      body: JSON.stringify({ <span class="hljs-keyword">address</span>: accounts[<span class="hljs-number">0</span>] })
    })

    const { message } <span class="hljs-operator">=</span> await response.json()
    
    <span class="hljs-comment">// Signer'dan imzalamasını isteyelim.</span>
    const signature <span class="hljs-operator">=</span> await signer.signMessage(message)
    console.log(signature)
  }
<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>script<span class="hljs-operator">></span>
</code></pre><p>public/index.html</p><p>Terminalde tekrardan npm start yapıp sayfayı yeniledikten sonra Ethereum ile Giriş Yap dediğinizde MetaMask sizden mesajı imzalamanızı isteyecek.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Ardından consoleda Ethereum adresinizle imzalanmış mesajı görebilirsiniz. Artık bu imzayı sunucuya gönderip kontrol etmek kaldı. Bu kontrolü yapan endpointimizi yazalım.</p><pre data-type="codeBlock" text="const ethers = require(&apos;ethers&apos;)

app.post(&apos;/auth/ethereum/verify&apos;, (req, res) =&gt; {
  let { address, signature } = req.body
  address = address.toLowerCase()

  const nonce = addressNonceMap[address]

  const message = `Welcome to there&apos;s no place like 127.0.0.1!\nClick &quot;Sign&quot; to sign in.\nWallet address: ${address}\n\nNonce: ${nonce}`

  // Istenilen mesaj ile imzalanmış mesajı kullanarak imzalayan adresi çıkart
  const recoveredAddress = ethers.utils.verifyMessage(message, signature)

  // Iddia edilen adres ile imzadan çıkartılan adres eşleşiyor mu?
  if (address === recoveredAddress.toLowerCase()) {
    res.json({
      status: true
    })
  } else {
    res.json({
      status: false
    })
  }
})
"><code><span class="hljs-keyword">const</span> ethers = <span class="hljs-built_in">require</span>(<span class="hljs-string">'ethers'</span>)

app.<span class="hljs-title function_">post</span>(<span class="hljs-string">'/auth/ethereum/verify'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =></span> {
  <span class="hljs-keyword">let</span> { address, signature } = req.<span class="hljs-property">body</span>
  address = address.<span class="hljs-title function_">toLowerCase</span>()

  <span class="hljs-keyword">const</span> nonce = addressNonceMap[address]

  <span class="hljs-keyword">const</span> message = <span class="hljs-string">`Welcome to there's no place like 127.0.0.1!\nClick "Sign" to sign in.\nWallet address: <span class="hljs-subst">${address}</span>\n\nNonce: <span class="hljs-subst">${nonce}</span>`</span>

  <span class="hljs-comment">// Istenilen mesaj ile imzalanmış mesajı kullanarak imzalayan adresi çıkart</span>
  <span class="hljs-keyword">const</span> recoveredAddress = ethers.<span class="hljs-property">utils</span>.<span class="hljs-title function_">verifyMessage</span>(message, signature)

  <span class="hljs-comment">// Iddia edilen adres ile imzadan çıkartılan adres eşleşiyor mu?</span>
  <span class="hljs-keyword">if</span> (address === recoveredAddress.<span class="hljs-title function_">toLowerCase</span>()) {
    res.<span class="hljs-title function_">json</span>({
      <span class="hljs-attr">status</span>: <span class="hljs-literal">true</span>
    })
  } <span class="hljs-keyword">else</span> {
    res.<span class="hljs-title function_">json</span>({
      <span class="hljs-attr">status</span>: <span class="hljs-literal">false</span>
    })
  }
})
</code></pre><p>app.js</p><pre data-type="codeBlock" text="// Signer&apos;dan imzalamasını isteyelim
const signature = await signer.signMessage(message)
console.log(signature)

// Imzayı sunucuya gönderelim
const verifyResponse = await fetch(&apos;/auth/ethereum/verify&apos;, {
    method: &apos;POST&apos;,
    headers: {
        &apos;content-type&apos;: &apos;application/json&apos;,
    },
    body: JSON.stringify({ address: accounts[0], signature })
})

const { status } = await verifyResponse.json()

let authMessage;

if (status) authMessage = `Auth successful! Welcome &lt;pre&gt;${accounts[0]}&lt;/pre&gt;`
else authMessage = `Auth failed. Please try again later or contact with us.`

document.querySelector(&apos;h1&apos;).innerHTML = authMessage
"><code><span class="hljs-comment">// Signer'dan imzalamasını isteyelim</span>
const signature <span class="hljs-operator">=</span> await signer.signMessage(message)
console.log(signature)

<span class="hljs-comment">// Imzayı sunucuya gönderelim</span>
const verifyResponse <span class="hljs-operator">=</span> await fetch(<span class="hljs-string">'/auth/ethereum/verify'</span>, {
    method: <span class="hljs-string">'POST'</span>,
    headers: {
        <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'application/json'</span>,
    },
    body: JSON.stringify({ <span class="hljs-keyword">address</span>: accounts[<span class="hljs-number">0</span>], signature })
})

const { status } <span class="hljs-operator">=</span> await verifyResponse.json()

let authMessage;

<span class="hljs-keyword">if</span> (status) authMessage <span class="hljs-operator">=</span> `Auth successful<span class="hljs-operator">!</span> Welcome <span class="hljs-operator">&#x3C;</span>pre<span class="hljs-operator">></span>${accounts[<span class="hljs-number">0</span>]}<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>pre<span class="hljs-operator">></span>`
<span class="hljs-keyword">else</span> authMessage <span class="hljs-operator">=</span> `Auth failed. Please <span class="hljs-keyword">try</span> again later or contact with us.`

document.querySelector(<span class="hljs-string">'h1'</span>).innerHTML <span class="hljs-operator">=</span> authMessage
</code></pre><p>public/index.html – signIn fonksiyonu devamı</p><p>Ethereum ile giriş özelliğini implemente ettik! Expressi yeniden başlatıp sayfayı yenilediğinizde artık siz de cüzdanınızla giriş yapabilirsiniz!</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><figcaption HTMLAttributes="[object Object]" class="">🎉🎉🎉🎉🎉</figcaption></figure><p>Açıkçası kodda bulunan <code>Auth failed.</code> mesajını UI&apos;ı kullanırken almanız oldukça güç. Sonuç olarak herhangi bir kullanıcı adı veya parola girmiyorsunuz :)</p><p>Demoyu olabildiğince basitleştirmek için veritabanı, <code>Auth token</code> gibi yapıları eklemedim. <code>Verify</code> edildikten sonra halihazırda yaptığınız şekilde bir Cookie veya <code>JWT token</code> istemciye sağlayabilirsiniz.</p><p>Sunucudan gönderdiğiniz mesajda <code>nonce</code> olması önemli. Statik bir mesaj üzerinden de adres doğrulaması yapmak mümkün ancak imzalanmış mesaj herhangi bir şekilde başka birine geçmesi durumunda aynı siteye bu signature kullanılarak defalarca giriş yapabilir. Aynı zamanda da aynı mesajı imzalatan diğer websitelerine de bu imzalanmış mesajı göndererek giriş yapabilir. Nonce önemli.</p><p>GitHub üzerinden koda ulaşabilirsiniz. Eğer herhangi bir projede Ethereum ile girişi kullanırsanız lütfen bana iletin, çok mutlu olurum :)</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/MrPeker/eth-sign-in">GitHub - MrPeker/eth-sign-in: Sample code for ETH Sign In</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/MrPeker/eth-sign-in">Sample code for ETH Sign In. Contribute to MrPeker/eth-sign-in development by creating an account on GitHub.</a></p><p>Aklınıza takılan herhangi bir soru varsa bana Twitter&apos;dan ulaşabilirsiniz</p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/mehmetalicode">https://twitter.com/mehmetalicode</a></p></li></ul><p>Görüşmek üzere 👋</p>]]></content:encoded>
            <author>peker@newsletter.paragraph.com (Mehmet Ali Peker)</author>
        </item>
    </channel>
</rss>