HUAWEI Ability Gallery —Native Android & Java Spring ile Account Binding

Kadirtas
7 min readJun 14, 2021

--

Günümüzde teknolojinin gelişmesiyle birlikte işlemlerin hızlanması bizleri beklenenin aksine daha da sabırsız yaptı. Eskiden çok uzun süren işlemler artık saniyelere düşmesine rağmen milisaniye düzeyinde bir gecikme olduğunda bile bazen bazı uygulamaları kullanmayı bırakabiliyoruz. Bu sebeple günümüz dünyasına ayak uydurmaya çalışan uygulamalar için kullanıcıları kaybetmemek açısından saliseler dahi çok önemlidir.

“vakit nakittir”

Örneğin, bir trading uygulamasında kullanıcının piyasayı kontrol ettiğini düşünelim. Bunun için uygulamayı bulup splash screen aşamasını beklemesi, bundan sonra login olması, istek sonucunun beklenmesi gibi birçok işlem var. Bu senaryoda kullanıcı gün içinde bunu yaklaşık 20 defa yaptığını düşünürsek bu gerçekten büyük bir zaman kaybı olacaktır. Bu sebeple kullanıcı kaybı olması kaçınılmaz olacaktır.

Bu sebeple uygulamalarımızı, Huawei Ability Gallery’nin sağladığı Card Ability veya Content Ability gibi özellikler sayesinde telefonunun -1 ekranında widget’lar oluşturup uygulama kullanıcılarının buradan daha spesifik bilgilere erişmesini sağlayabiliriz. Bu sayede sadece bu kullanıcı kaybından kurtulmakla kalmayıp ayrıca yeni kullanıcılar da kazanabiliriz.

Bu yazımda Huawei Ability Gallery(HAG)’nin sağladığı Card Ability özelliği ile kullanıcılarımızın verilerini senkronize edebilmek için account binding işleminden bahsedeceğim. Daha çok işlemin teknik tarafta nasıl yapıldığını anlatmaya çalışacağım.

Not: Console tarafında yapılan işlemler ve daha teorik bilgiler için bu makaleyi okumanızı tavsiye ederim.

Account Binding’in 2 farklı yöntemi vardır. Birinci yöntemde Huawei ID kullanılmadan developer’ın kendi sign-in yönteminin olduğu uygulamalar için account binding yapılır. İkinci yöntemde ise Huawei ID kullanılarak account binding yapılır. Bu sayede kullanıcılarımızın verilerini “-1” ekranındaki widget’ımızla ve uygulamamızla senkronize ederiz.

Peki bu iki yöntem arasındaki fark nedir?

Huawei ID kulanılarak account binding yapılan senaryoda, client tarafında Auth Service olduğu için, Client OpenID’yi her zaman elde edebilir. Ve senkronizasyonu bu id ye göre yapabilir. Bu sebeple userID ve OpenID pairini DB’de tutmamıza gerek yoktur. Çünkü senkronizasyon sağlamak istediğimizde client tarafından Auth service sayesinde OpenID elde edilir ve backend’e OpenID gönderdiğimizde zaten bunu daha önce DB’de kaydettiğimiz için senkronizasyon sağlayabiliriz. Backend’de ekstra bir userID tutmaya gerek yoktur.

Ancak bizim bu demoda yapacağımız olan senaryoda, yani Huawei ID kullanılmadan kendi sign-in yöntemimizi kullandığımız Account Binding senaryosunda, Auth Service olmadığı için Client’ın OpenID’ye erişimi yoktur. Ancak ve ancak ilk account binding aşamasında deeplink ile birlikte OpenID elde edilebilir. Bu sebeple, userId ve OpenID pair’ini kaydediyoruz ki client’dan bir daha OpenID istemeden senkronizasyonu sağlayabilelim. Çünkü sadece userID yi backend’e gönderince, bu userID ye göre senkronizasyon sağlayabiliriz. Bunu da backend’deki userID openID pair’ine göre, gelen userID ye denk gelen OpenID’yi HAG server ‘a bildirerek yapıyoruz.

Ayrıca Custom sign-in yöntemi mevcut olan uygulama’da, yani Huawei ID kullanılmadan account binding yapmanın ve Huawei ID kullanarak account binding yapmanın arasındaki farkı aşağıdaki diagramda görebilirsiniz.

Not: Bu diyagramda, demo kısmındaki ve official dokümandaki implementation process ile adımların karışmaması için ve bu yazının konu kapsamının başlangıcı olduğu için ilk adım olarak 5. adım olarak numaralandırdım.

Huawei ID kullanılmadan Developer’ın kendi sign-in yöntemine göre Account Binding yapmayı daha iyi anlatabilmek için client tarafta Native App olan bir demo yapacağız. Backend de ise Java Spring kullanacağız. Şimdi geliştirme aşamalarına geçebiliriz.

Demo Geliştirme

Bu demomuzda bir e-commerce uygulaması senaryosunda Account Binding kullanacağız. Bu sayede -1 ekranında Card Ability özelliğini kullandığımız widget’a Account Binding ile kullanıcının hesabını bağlayacağız.

Account Binding kullanarak, kullanıcıların hesaplarını bağlamak için aşağıdaki implementation process’i takip ediyor olacağız. Ancak buna ek olarak araya bir step daha ekleyip server side authentication yapmamız gerektiğini belirtmeliyim. Çünkü Account Binding işlemini HAG server’a bildirirken header’da bir access token’a ihtiyacımız olacak.

Şimdi adım adım neler yapacağımızdan bahsetmek istiyorum. Bu anlatımı overview olarak düşünebilirsiniz. Sonrasında her aşamada yazılacak kodları anlatacağım. Anlatım sırasında kaybolmamak için yukarıdaki diagram’ı takip edebilirsiniz. Çünkü biz de bu diagram’a bağlı ilerleyeceğiz.

Biz burada, server tarafındaki ve client tarafındaki geliştirmelerden bahsedeceğimiz için, 5. adımdan itibaren başlıyoruz. Öncelikle Huawei Ability Gallery tarafından bir OpenID server’ımıza geliyor. Bizim, gelen request’e bu OpenID ile bir deeplink dönmemiz gerekmektedir. Bu deeplink uygulamamızın sign in sayfası olmalıdır. HAG bu deeplink’i çalıştırınca uygulamamızın sign in sayfası gelmektedir. Burada sign olmasını bekliyoruz ki uuid ile OpenID match’imiz de bir yanlışlık olmasın. Yani doğru kullanıcı id’sini match etmek istiyoruz. Kullanıcı uygulamada açılan sign in sayfasında sign in olduktan sonra, kullanıcının id’si ile deeplink ile gelen OpenID’yi match etmek için server’ımıza gönderiyoruz. Son olarak da Match işleminin ardından sonucu HAG server’a bildirmemiz gerekmektedir. Ve bu şekilde Account Binding’i tamamlamış oluyoruz.

Bunun sonucunda elde ettiğimiz şey, kullanıcılarımızın hesaplarını -1 ekranındaki Huawei Ability Gallery’nin sağlamış olduğu Card Ability widget’ına bağlamaktır.

Şimdi ilk adım için (bizim başlangıcımız olan 5. adım için) öncelikle client tarafında bir deeplink belirlemeliyiz. Bu demo uygulamamızda Navigation Component kullandığımız için navigation_main.xml dosyamızda sign in fragment tag ‘inin içine bir deeplink tag’i ekliyoruz.

Ardından manifest dosyamızda activity tag’inin içine nav graph’ımız ekliyoruz.

<nav-graph android:value="@navigation/sign_in_graph"/>

Şimdi bu deeplink’i HAG server’ına gönderiyoruz. Bu şekilde HAG kullanıcının cihazında bu deeplink’i çalıştıracak ve kullanıcıyı uygulamamızın sign in sayfasına yönlendireceğiz.

Bunun için HAG’nin deeplink’i almak için istek atacağı endpoint’i hazırlamamız gerekmektedir. Şimdi backend tarafına geçip burada Controller’ı yazmamız gerekmektedir. Ancak öncelikle bu Controller’da kullanacağımız class ve interface’leri oluşturmalıyız. Controller ile servis arasında bağlantı yaparken test edilebilirliği kolaylaştırmak için ve daha iyi bir yapı oluşturmak için interface kullanacağız. Bunun için öncelikle HAGService interface’imizi oluşturuyoruz.

Burada ben bir daha bu interface’i ekleyip yazıyı uzatmamak için ileride de kullanacağımız tüm fonksiyonları ekledim. Ancak 5.adım için şu anda sadece getLoginDeeplink fonksiyonunu kullanacağız.

Şimdi bu fonksiyonun parametresi olan AccountBindingHAGDeeplinkRequest objesini oluşturalım. Burada bizim yapacağımız demoda sadece OpenID’ye ihtiyacımız olduğu için AccountBindingHAGDeeplinkRequest modeli aşağıdaki gibi olması işimizi görecektir (Ayrı ayrı objeleri oluşturmak çok yer kaplayacağı için java class’ları yerine json dosyasını paylaşıyorum. Sizler geliştirme yaparken bu json dosyasını temsil edecek class’ları oluşturmanız gerekecektir.):

Ayrıca bir de HAGServer’ın kabul edeceği şekilde bir response class’ı oluşturmalıyız. Aşağıda iç içe olan class’ların hepsini yazıp yer kaplamasını istemediğimden dolayı json halini yazıyorum. Ancak sizin, bu json dosyasını temsil edecek objeleri oluşturmanız gerekmektedir.

Not: Unutmayın object mapping olacağı için oluşturacağınız class property’lerinin ismi json dosyasındakiler ile tamamen aynı olmalıdır.

AccountBindingHAGDDeeplinkResponse.java (Temsili json objesi) :

Burada her property’nin case sensitive olduğunu ve “reply”, “accountLoginAddr” ve “deepLink” in iç içe objeler olduğunu unutmayın. Ayrıca “minVersion” un da Long türünde olduğunu unutmamalıyız.

Şimdi oluşturduğumuz formatta request 'den OpenID’yi alacağımız ve yine oluşturduğumuz formatta response mesaj oluşturma işlemlerini yapacağımız HAGServiceImpl class’ımızı yazalım. Bu class HAGService interface’ini implemente edecektir.

Burada AccountBindingHAGReply gibi objeler benim json objesini temsil etmek için oluşturduğum objelerdir.

Response mesaj oluştururken aşağıdaki değerlerle doldurmalıyız:

  • version: “1.0”
  • url: uygulamamızın sign in sayfasına tanımladığımız deeplink’i ve sonuna request’den gelen OpenID’yi ekliyoruz
  • appPackage: uygulamamızın package name’i
  • minVersion: 1l
  • errorCode: “0”
  • errorMessage: “ok”

Oluşturduğumuz service implementation classımızı Controller’a bağlayacağız. Controller’a gelen sign in sayfasının deeplink’ini alma request’ini buraya gönderip, burada response mesajı HAG Server’ın alacağı formatta oluşturarak return edeceğiz.

Şimdi Controller’ımızı oluşturalım:

Burada bir önceki aşamada yazdığımız service class’ımızı autowire ettik. HAG server console tarafında belirteceğimiz url’e POST request atacağı için bu request’i handle edeceğimiz accountBinding metotuna @PostMapping annotasyonunu ekledik. HAG server buraya OpenID’yi body’de ve daha önce oluşturduğumuz request objesi formatında göndereceği için, bu fonksiyon parametre olarak bu oluşturduğumuz request objesini, başında @ResponseBody annotasyonu ile birlikte almalı. Bu şekilde fonksiyonumuzu oluşturduktan sonra, gelen parametreyi oluşturduğumuz service paslayarak deepLink response’unu elde edip return ediyoruz.

Not: Bu fonksiyon ve Controller’a göre HAG console’da account binding için belirtmemiz gereken url “ ‘domain’iniz’ /hag/account/bind” olmalıdır.

Buradan sonra HAG, 6. adım olarak döndüğümüz deeplink’i sonundaki OpenID ile birlikte run ederek uygulamamızın sign in sayfasını açacaktır. 7.adımda kullanıcı hesap bilgilerini girecektir. Eğer sign in işlemi başarılı olursa, 8.adım olarak deeplink ile birlikte elde ettiğimiz OpenID’yi ve kullanıcı id’sini backend’imize göndereceğiz.

Not: Burada standart bir şekilde retrofit kullanarak http request atacağımız için client tarafındaki işlemleri, bu blog’u uzatmamak için eklemiyorum. Ancak siz sign in başarılı olduktan sonra, kendi backend’inize göre standart bir http request ile kullanıcının ID’sini ve OpenID’sini backend’inize gönderebilirsiniz.

9. adım olarak id match’lerini database’imize kaydedeceğiz. Burada Repository oluşturduktan sonra ve backend’inize göre gerekli verification adımlarınızı yaptıktan sonra database’e yazma işlemini tamamlıyoruz. Ve 10. adım olarak da HAG server’ına bildiriyoruz. Bunun için WebClient kullanarak HAG server’ın account binding url’ine request atıyoruz. Bu request için öncelikle header da ihtiyacımız olan Bearer token’ı almalıyız. Bunun için de yine WebClient kullanacağız.

Token alacağımız url content type olarak olarak url-encoded desteklediği için bir form data oluşturuyoruz. Bu form data yukarıdaki gibi grant_type, client_id ve client_secret değerlerini içermelidir. Burada sizin kendi projenize göre doldurmanız gereken alanlar;

  • client_id
  • client_secret

değerleridir. Bu değerlere console’dan ulaşabilirsiniz.

Ardından WebClient kullanarak TOKEN_URL’e POST request atarak, account binding için atacağımız request’in header’ında ihtiyacımız olan Bearer token’ı elde ediyoruz.

Şimdi de account binding sonucunu bildirmek için HAG server’a atacağımız request’in body’sini oluşturmalıyız.

Son olarak da bu fonksiyonları kullanarak elde edeceğimiz değerlerle birlikte HAG server’ına account binding’i bildirmek için request atacağız.

Burada parametre olan openID uygulamadan atılan id match request’inden gelmektedir.

Bu şekilde uygulamamızın kullanıcıları hesaplarını Huawei Ability Gallery’nin sağladığı Card Ability özelliği ile bağlayabilecektir.

Unbind için ise sadece BIND_URL’i değiştirmemiz gerekmektedir. Geri kalan tüm işlemler aynıdır.

Unbind URL: https://hag-eu.cloud.huawei.com/open-ability/v1/open-account-events/unbind

--

--