<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringCloud微服務(wù)架構(gòu)實戰(zhàn):商家權(quán)限體系設(shè)計及開發(fā)

          共 9534字,需瀏覽 20分鐘

           ·

          2022-04-10 18:16


          商家管理后臺與sso設(shè)計

          在本文的電商平臺實例中,商家是這個平臺的主角,商家管理后臺是專門為這個主角提供的一個安全可靠的操作平臺。在商家管理后臺中,商家可以進(jìn)行商品管理、訂單管理、物流管理、會員管理、評價管理等各個方面的管理工作。這些管理功能及其服務(wù)功能分別由不同的微服務(wù)項目實現(xiàn),并通過不同的應(yīng)用進(jìn)行部署?,F(xiàn)在我們要做的,就是將這些分布在不同應(yīng)用中的管理功能,組成一個具有相同訪問控制設(shè)計的管理后臺。

          單點登錄(Single Sign On,SSO)設(shè)計可以將這種分散的應(yīng)用,通過統(tǒng)一的訪問控制和權(quán)限管理,整合成一個有機(jī)整體,為分布式環(huán)境中的不同應(yīng)用,提供一個統(tǒng)一的登錄控制和授權(quán)認(rèn)證管理。商家管理員只需在任何一個應(yīng)用中登錄一次,就可以得到使用其他應(yīng)用的權(quán)限。所以,不管商家管理后臺的功能由多少個微服務(wù)應(yīng)用組成,對于一個商家管理員來說,它始終只是一個完整的平臺。

          商家管理后臺的設(shè)計和開發(fā)主要由商家管理開發(fā)和SSO開發(fā)兩部分組成。其中,商家管理開發(fā)主要包含商家信息管理及其權(quán)限體系設(shè)計兩部分。

          這些設(shè)計集中在商家管理微服務(wù)項目merchant-microservice 中進(jìn)行開發(fā),完整的源代碼可以從本書源代碼中下載,本章的實例對應(yīng)分支V2.1。

          商家及其權(quán)限體系設(shè)計由 merchant-object、merchant-domain、merchant-restapi、merchant-client和 merchant-web等模塊組成。SSO設(shè)計由merchant-sso模塊和merchant-security模塊組成。SSO的客戶端接入可通過merchant-web模塊進(jìn)行體驗。


          商家權(quán)限體系的設(shè)計及開發(fā)

          商家權(quán)限體系設(shè)計由權(quán)限管理模型和菜單管理模型兩大功能模型組成。其中,權(quán)限管理模型包含商家、用戶、角色等實體設(shè)計,菜單管理模型包含資源、模塊、分類等實體設(shè)計。兩大模型之間通過角色與資源的關(guān)聯(lián)關(guān)系,組成一個完整的權(quán)限菜單體系結(jié)構(gòu),如圖10-1所示。


          在圖10-1中,實體之間的關(guān)聯(lián)關(guān)系使用單向關(guān)聯(lián)設(shè)計,關(guān)聯(lián)關(guān)系如下所示:

          • 用戶從屬于商家,是多對一的關(guān)聯(lián)關(guān)系。

          • 用戶擁有角色,是多對多的關(guān)聯(lián)關(guān)系。

          • 角色擁有資源,是多對多的關(guān)聯(lián)關(guān)系。

          • 資源從屬于模塊,是多對一的關(guān)聯(lián)關(guān)系。

          • 模塊從屬于分類,是多對一的關(guān)聯(lián)關(guān)系。

          在圖10-1所示的關(guān)聯(lián)關(guān)系中,箭頭所指一方為關(guān)聯(lián)關(guān)系的主鍵,另一方為外鍵。其中,用戶與角色、角色與資源分別使用一個中間表來存儲關(guān)聯(lián)關(guān)系。

          這些對象所對應(yīng)的物理模型,經(jīng)過PowerDesigner 設(shè)計之后,最后完成的表格定義及其關(guān)聯(lián)關(guān)系如圖10-2所示。


          在圖10-2中,商家、用戶、角色、資源、模塊和分類等表格分別為t_merchant、
          t_usert_role.t_resource.t_model和 t_kind,用戶與角色、角色與資源的關(guān)聯(lián)關(guān)系的表格分別為user_role和role_resource。此外,表格persistent_logins是在用戶處于登錄狀態(tài)時,用來存儲臨時數(shù)據(jù)的。

          權(quán)限管理模型設(shè)計

          權(quán)限管理模型主要由商家、用戶、角色、資源、模塊和分類等實體組成。下面對這些實體分別進(jìn)行簡要說明。

          商家實體主要由ID、名稱、郵箱、電話、地址、聯(lián)系人和創(chuàng)建日期等屬性組成,實現(xiàn)代碼如下所示:

          @Entity
          @Table(name = "t merchant")
          public class Merchant implements java.io.Serializable{
          @Id
          @GeneratedValue(strategy =GenerationType.IDENTITY)private Long id;
          private String name;private String email;private String phone;private String address;private String linkman;
          @DateTimeFormat(pattern = "yyyY-MM-dd HH:mm:ss")
          @column (name = "created",columnDefinition = "timestamp defaultCurrent timestamp")
          @Temporal (TemporalType.TIMESTAMP)private Date created;
          // 0neToMany (cascade ={ },mappedBy ="merchant")// private List users;
          public Merchant() {
          }
          ...
          }

          用戶實體主要由ID、名稱、密碼、郵箱、性別和創(chuàng)建日期等屬性組成,實現(xiàn)代碼如下所示:

          @Entity
          @Table(name = "tuser")
          public class User implements java.io.Serializable{
          @Id
          @GeneratedValue (strategy = GenerationType.IDENTITY)private Long id;
          private String name;private String password;private String email;
          eColumn (name = "sex",length= 1,columnDefinition = "tinyint")private Integer sex;
          @DateTimeFormat (pattern= "YyyY-MM-dd HH:mm: ss")
          eColumn (name = "created", columnDefinition = "timestamp defaultcurrent timestamp ")
          @Temporal (TemporalType.TIMESTAMP)private Date created;
          @ManyToMany (cascade = {,fetch = FetchType.EAGER)@JoinTable(name = "user role",
          joinColumns ={@JoinColumn (name = "user id")],
          inverseJoinColumns -{GJoinColumn (name = "role_id")})
          private List roles;
          @ManyTo0ne
          CJoinColumn(name = "merchant_id")@JsonIgnore
          private Merchant merchant;
          public User() {
          }
          ...
          }

          其中,@ManyToMany是一個多對多的正向關(guān)聯(lián)關(guān)系,這里使用一個中間表user_role保存關(guān)聯(lián)關(guān)系的數(shù)據(jù)。

          @ManyToOne是一個反向關(guān)聯(lián)設(shè)計,即使用mercnant_1a TFAh廣oPIl Mo體建立關(guān)聯(lián)關(guān)系。

          角色實體由ID、名稱和創(chuàng)建日期等屬性組成,實現(xiàn)代碼如下所示:

          @Entity
          @Table(name ="t role")
          public class Role implements java.io.Serializable{
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;
          private String name;
          @DateTimeFormat (pattern = "yyyy-MM-dd HH:mm:ss")
          eColumn(name = "created",columnDefinition = "timestamp defaultcurrent timestamp ")
          @Temporal (TemporalType.TIMESTAMP)private Date created;
          @ManyToMany(cascade = {}, fetch = FetchType.EAGER)
          @JoinTable(name = "role resource",
          joinColumns = {@JoinColumn (name - "role_id")},
          inverseJoinColumns = {@JoinColumn (name = "resource_id")))
          private List resources;
          public Role() {
          }
          ...
          }

          角色實體與資源實體是一個多對多的關(guān)聯(lián)關(guān)系,因此使用@ManyToMany進(jìn)行設(shè)置。通過這種關(guān)聯(lián)關(guān)系,可以將權(quán)限管理模型與菜單管理模型組成一個完整的商家權(quán)限體系。

          資源實體由ID、名稱、統(tǒng)一資源定位和創(chuàng)建日期等屬性組成,實現(xiàn)代碼如下所示:

          @Entity
          @Table(name ="t resource")
          public class Resource implements java.io.Serializable {
          @Id
          @GeneratedValue (strategy =GenerationType.IDENTITY)private Long id;
          private string name;private string url;
          @DateTimeFormat (pattern = "yyyy-MM-dd HH:mm:ss")
          @Column (name = "created", columnDefinition = "timestamp defaultcurrent timestamp")
          @Temporal(TemporalType.TIMESTAMP)private Date created;
          @ManyToOne
          @JoinColumn(name = "mid")@JsonManagedReference
          private Model model;
          public Resource() {
          }
          ...
          }

          資源實體與模塊的關(guān)聯(lián)關(guān)系同樣使用@ManyToOne進(jìn)行反向關(guān)聯(lián)設(shè)計,這與用戶與商家的關(guān)聯(lián)關(guān)系的設(shè)計原理相同。

          模塊實體由ID、名稱、主機(jī)、圖標(biāo)和創(chuàng)建日期等屬性組成,實現(xiàn)代碼如下所示:

          @Entity
          @Table(name ="tmodel")
          public class Model implements java.io.Serializable{
          @Id
          @Generatedvalue(strategy -GenerationType.IDENTITY)private Long id;
          private String name;private String host;private String icon;
          @DateTimeFormat (pattern = "yyyy-MM-dd HH:mm:ss")
          eColumn (name = "created", columnDefinition = "timestamp defaultcurrent timestamp")
          @Temporal (TemporalType.TIMESTAMP)private Date created;
          @ManyTo0ne
          @JoinColumn (name = "kid")@JsonIgnore
          private Kind kind;
          public Model() {}
          ...
          }

          模塊實體的關(guān)聯(lián)關(guān)系設(shè)計與資源實體的關(guān)聯(lián)設(shè)計一樣,也是使用@ManyToOne進(jìn)行反向關(guān)聯(lián)設(shè)計的。

          分類實體由ID、名稱、鏈接服務(wù)和創(chuàng)建日期等屬性組成,實現(xiàn)代碼如下所示:

          @Entity
          @Table(name = "t kind")
          public class Kind implements java.io. Serializable{
          @Id
          @Generatedvalue (strategy =GenerationType.IDENTITY)private Long id;
          private String name;private String link;
          @DateTimeFormat (pattern= "yyyy-MM-dd HH:mm:ss")
          cColumn (name = "created", columnDefinition = "timestamp defaultcurrent timestamp")
          @Temporal (TemporalType.TIMESTAMP)private Date created;
          public Kind() {}
          ...
          }

          分類實體在菜單模型結(jié)構(gòu)中是一個頂級菜單,所以不需要進(jìn)行關(guān)聯(lián)設(shè)計。

          單向關(guān)聯(lián)設(shè)計可以提高數(shù)據(jù)的訪問性能,但也有不足的地方。比如,在角色實體中,已經(jīng)實現(xiàn)了角色實體與資源實體的單向關(guān)聯(lián)設(shè)計,因此從角色實體中查詢資源列表,則是非常容易的。但是反過來,從資源實體中查詢角色列表就有些費(fèi)力了。為了彌補(bǔ)這種不足,可以使用SQIL查詢語句實現(xiàn),具體會在后面的持久化設(shè)計中進(jìn)行說明。

          權(quán)限管理模型的持久化設(shè)計

          在權(quán)限管理模型設(shè)計完成之后,為各個實體創(chuàng)建一個存儲庫接口,并與JPA的存儲庫接口進(jìn)行綁定,就可以給實體賦予操作行為,實現(xiàn)實體的持久化設(shè)計。這一過程,其實就是存儲庫接口設(shè)計的工作。

          例如,可以創(chuàng)建一個如下所示的存儲庫接口實現(xiàn)商家實體的持久化設(shè)計:

          @Repository
          public interface MerchantRepository extends JpaRepository<Merchant,Long>,JpaSpecificationExecutor<Merchant> {
          }

          在這個接口設(shè)計中,通過繼承JpaRepository,可以讓這個接口具有增刪改查的操作功能。再通過繼承.JpaSpecificationExecutor,就可以進(jìn)行復(fù)雜的分頁查詢設(shè)計。如果不做其他特殊的查詢設(shè)計,這樣就已經(jīng)完成了商家實體的持久化設(shè)計了。

          如果對于一個實體,還需要實現(xiàn)一些復(fù)雜的查詢設(shè)計,如對用戶實體進(jìn)行持久化設(shè)計,則使用如下所示的代碼:

          @Repository
          public interface UserRepository extends JpaRepository<User, Long>,JpaSpecificationExecutor<User> {
          cQuery ("select distinct u from User u where u.name= :name")User findByName (@Param ("name") String name) ;
          @Query("select u from User u"+
          " left join u.roles r"
          "where r.name= :name")

          User findByRoleName (@Param ("name") String name) ;
          @Query ("select distinct u from User u where u.id= :id")User findById(@Param( "id") Long id);
          @Query ( "select u from User u"+
          "left join u.roles r "+"where r.id = :id")
          List findByRoleId(@Param("id") Long id);
          }

          這里多了幾個使用注解“@Query”進(jìn)行自定義查詢設(shè)計的聲明方法。

          其中,findByName和findByld主要使用distinct進(jìn)行了去重查詢,以避免在多對多的關(guān)聯(lián)查詢中,出現(xiàn)數(shù)據(jù)重復(fù)的情況。

          另外,findByRoleName和 findByRoleld就是前面提到的,為彌補(bǔ)單向關(guān)聯(lián)設(shè)計的不足而設(shè)計的查詢。findByRoleName實現(xiàn)了從角色名稱中查詢用戶列表的功能,而findByRoleld實現(xiàn)了從角色I(xiàn)D中查詢用戶列表的功能。

          在角色實體存儲庫接口設(shè)計中,也需要增加一個查詢設(shè)計,代碼如下所示:

          @Repository
          public interface RoleRepository extends JpaRepository<Role,Long>,JpaSpecificationExecutor<Role>{
          CQuery("select o from Role o"+
          "left join o.resources r"+"where r.id = :id")
          List findByResourceId(@Param("id") Long id);
          }

          在這個設(shè)計中,findByResourceld是一個反向關(guān)聯(lián)查詢,即使用資源ID查詢角色列表。

          其他實體的持久化設(shè)計與商家實體的持久化設(shè)計類似,只需為它們創(chuàng)建一個存儲庫接口就可以了。

          權(quán)限管理模型的服務(wù)封裝

          在領(lǐng)域服務(wù)開發(fā)中,服務(wù)層的實現(xiàn)是對存儲庫接口調(diào)用的一種封裝設(shè)計,這樣,不但可以在存儲庫接口調(diào)用過程中實現(xiàn)統(tǒng)一的事務(wù)管理,還可以增加其他功能。

          下面我們以用戶服務(wù)層的開發(fā)為例進(jìn)行說明,其他各個業(yè)務(wù)服務(wù)層的開發(fā)與此類似,不再贅述。

          在用戶服務(wù)層的設(shè)計中,增刪改查各個操作的實現(xiàn)代碼如下所示:@Service

          @Transactional
          public class UserService {
          CAutowired
          private UserRepository userRepository;
          public String insert (User user){
          try {
          User old = findByName(user.getName());if(old == null) {
          userRepository.save(user);
          return user.getId() .toString();}else{
          return "用戶名' "+ old.getName()+ "'已經(jīng)存在!";
          }catch(Exception e){
          e.printStackTrace();return e.getMessage();
          public String update (User user){
          try {
          userRepository.save(user);
          return user.getId() .toString();}catch(Exception e){
          e.printStackTrace();return e.getMessage ();
          }
          }
          public String delete (Long id){
          try {
          userRepository.deleteById(id);return id.toString ();
          }catch (Exception e){
          e.printStackTrace();
          return e.getMessage();
          }
          }
          public User find0ne (Long id){
          return userRepository.findByUserId(id);
          }
          public List findA11(){
          return userRepository.findAl1();
          }
          }

          在這個設(shè)計中,注解@Transactional 實現(xiàn)了隱式的事務(wù)管理功能。由于登錄用戶必須以用戶名為依據(jù),所以在新增用戶名時,做了同名檢測。

          用戶領(lǐng)域服務(wù)的分頁查詢功能的實現(xiàn)代碼如下所示:

          @service
          @Transactional
          public class UserService {
          CAutowired
          private UserRepository userRepository;
          public Page findAl1 (UserQo userQo){
          Sort sort = Sort.by(Sort.Direction. DESC, "created");
          Pageable pageable = PageRequest.of (userQo.getPage(), userQo.getSize(.
          sort);
          return userRepository.findAll(new Specification(){
          @override
          public Predicate toPredicate(Root root, CriteriaQueryqu
          CriteriaBuilder criteriaBuilder
          )
          {
          List predicatesList =new ArrayList();
          if (CommonUtils.isNotNull (userQo.getName())){
          predicatesList.add (criteriaBuilder.like(root.get ("name"),
          "g"+userQo.getName() +"%"));
          }
          if(CommonUtils.isNotNull (userQo.getMerchant ())){
          predicatesList.add (criteriaBuilder.equal (root. get ("merchant"),userQo.getMerchant().getId()));
          }
          if (CommonUtils.isNotNull(userQo.getCreated())){
          predicatesList.add(criteriaBuilder.greaterThan(root.get ("created"),userQo.getCreated()));
          query.where (predicatesList.toArray(new Predicate[predicatesList.
          size()]));
          return guery.getRestriction();
          }
          }, pageable);
          }
          }

          這里主要使用findAll 方法實現(xiàn)分頁查詢的功能,并通過查詢對象userQo 傳遞查詢參數(shù),這些參數(shù)包含了用戶名稱、商家對象和創(chuàng)建日期等屬性。

          在領(lǐng)域服務(wù)設(shè)計中,我們使用了一些查詢對象,這些查詢對象統(tǒng)一在merchant-object模塊中實現(xiàn)。查詢對象的屬性基本上與實體對象的屬性相互對應(yīng),并且還增加了幾個分頁查詢的屬性。

          查詢對象的實現(xiàn)代碼如下所示:

          public class User0o extends PageQo implements java.io.Serializable{
          private Long id;
          private String name;
          private String password;private String email;private Integer sex;
          @DateTimeFormat (pattern = "Yyyy-MM-dd HH:mm:ss")private Date created;
          private Listroles = new ArrayList<>();
          private MerchantQo merchant;
          public UserQ0() {
          }
          ...
          }

          在完成服務(wù)層開發(fā)之后,商家權(quán)限體系的設(shè)計基本告一段落。下篇我們對商家管理微服務(wù)進(jìn)行設(shè)計。

          本文給大家講解的內(nèi)容SpringCloud微服務(wù)架構(gòu)實戰(zhàn)商家管理后臺與sso設(shè)計:商家權(quán)限體系的設(shè)計及開發(fā)

          1. 下篇文章給大家講解的是商家管理后臺與sso設(shè)計:商家管理微服務(wù)設(shè)計;

          2. 覺得文章不錯的朋友可以轉(zhuǎn)發(fā)此文關(guān)注小編;

          3. 感謝大家的支持!


          本文就是愿天堂沒有BUG給大家分享的內(nèi)容,大家有收獲的話可以分享下,想學(xué)習(xí)更多的話可以到微信公眾號里找我,我等你哦。

          瀏覽 78
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操逼逼综合网 | 亚洲欧美在线免费 | 午夜无码久久 | 中文字幕第59页 | 婷婷啪啪|